gpt4 book ai didi

javascript - 强制 IntersectionObserver 更新

转载 作者:行者123 更新时间:2023-12-01 14:44:49 25 4
gpt4 key购买 nike

有什么方法可以强制更新/运行 IntersectionObserver实例?默认情况下,当视口(viewport)发生更改时,将执行回调。但是我正在寻找一种在其他事件发生时执行它的方法,比如元素的变化。

一个例子:

在初始化时,一切都按预期工作。但是当你改变 #red 的位置时元素,没有任何 react 。

// elements
let green = document.querySelector('#green');
let red = document.querySelector('#red');

// observer callback
let callback = entries => {
entries.forEach(entry => {
let isInside = entry.intersectionRatio >= 1 ? "fully" : "NOT";
console.log("#" + entry.target.id + " is " + isInside + " inside #container");
});
};

// start observer
let options = {root: document.querySelector('#container')};
let observer = new IntersectionObserver(callback, options);
observer.observe(green);
observer.observe(red);

// button action
document.querySelector('button').addEventListener('click', () => {
red.style.right = red.style.right == "" ? "0px" : "";
});
#container {
width: 100px;
height: 100px;
background: blue;
position: relative;
}

#green, #red {
width: 50px;
height: 50px;
background: green;
position: absolute;
}

#red {
background: red;
right: -10px;
}
<button>move #red</button>
<br /><br />
<div id="container">
<div id="green"></div>
<div id="red"></div>
</div>


有什么办法可以使这个工作吗?唯一可行的方法是 unobserve元素和开始 observing再说一遍。这可能适用于单个元素,但如果 Observer 有数百个元素要观察,则不行。

// elements
let green = document.querySelector('#green');
let red = document.querySelector('#red');

// observer callback
let callback = entries => {
entries.forEach(entry => {
let isInside = entry.intersectionRatio >= 1 ? "fully" : "NOT";
console.log("#" + entry.target.id + " is " + isInside + " inside #container");
});
};

// start observer
let options = {root: document.querySelector('#container')};
let observer = new IntersectionObserver(callback, options);
observer.observe(green);
observer.observe(red);

// button action
document.querySelector('button').addEventListener('click', () => {
red.style.right = red.style.right == "" ? "0px" : "";
observer.unobserve(red);
observer.observe(red);
});
#container {
width: 100px;
height: 100px;
background: blue;
position: relative;
}

#green, #red {
width: 50px;
height: 50px;
background: green;
position: absolute;
}

#red {
background: red;
right: -10px;
}
<button>move #red</button>
<br /><br />
<div id="container">
<div id="green"></div>
<div id="red"></div>
</div>

最佳答案

我认为在不调用节点上的 unobserve/observe 的情况下强制交叉观察者进行更新是不可能的,但您可以通过将所有观察到的节点保存在一组中来执行此操作:

class IntersectionObserverManager {
constructor(observer) {
this._observer = observer;
this._observedNodes = new Set();
}
observe(node) {
this._observedNodes.add(node);
this._observer.observe(node);
}
unobserve(node) {
this._observedNodes.remove(node);
this._observer.unobserve(node);
}
disconnect() {
this._observedNodes.clear();
this._observer.disconnect();
}
refresh() {
for (let node of this._observedNodes) {
this._observer.unobserve(node);
this._observer.observe(node);
}
}
}

编辑:使用 Set而不是 WeakSet因为他们是 iterable因此无需检查是否正在为正文中的每个元素观察该元素。小心调用 unobseve为了避免内存问题。

关于javascript - 强制 IntersectionObserver 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51402840/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com