ami*_*mik 5 javascript resize-observer
当某些观察到的元素从 DOM 中删除时,我应该调用.unobserve该元素以防止内存泄漏,还是会“自动不被观察到”?
const ro = new ResizeObserver((entries) => { console.log(entries); });
const el = document.getElementById('foo');
ro.observe(el);
// ... some time later
el.remove();
ro.unobserve(el); // <-- is this needed, or does it happen automatically behind the scenes?
Run Code Online (Sandbox Code Playgroud)
为什么我问:我正在实现一个观察许多孩子的 React 组件,并正确清理未安装组件的观察者将涉及非平凡的代码,如果实际上不需要它,我想避免这种情况。
mcm*_*mik 15
根据csswg-drafts存储库中的问题,现在,如果您从 DOM 中删除该元素并从 JS 中删除任何引用,Chrome 会自动取消观察该元素。
Run Code Online (Sandbox Code Playgroud)let el = document.querySelector("#id"); let ro = new ResizeObserver(); ro.observe(el); setTimeout(_ => { el.remove(); el = null; }如果没有 JS 引用,当前的 Chrome 代码会隐式取消观察元素。规范中没有捕获这一点。
但问题仍然悬而未决...
是的,你应该使用unobserve()或diconnect()。对于我自己的项目,当我不使用它时,我的应用程序中出现了内存泄漏。
我也发现使用很.unobserve()混乱。但如果提供了拆解......一般来说,使用它可能是一个很好的做法。在开发代码时添加绝对比在忘记为什么做某事后进行更新更容易。
我也在使用 React,但我使用 useEffect 钩子来清理它。
我必须进行一些尝试和错误才能找出有效的方法,并且最初也错过了.disconnect()对 ResizeObserver 的调用。
所以目前对我有用的是:
const [height, setHeight] = useState(null);
useEffect(() => {
const heightObserver = new ResizeObserver((entries) => {
setHeight(entries[0].contentRect['height']);
});
heightObserver.observe(el);
return () => {
if(el){
heightObserver.unobserve(el);
} else {
heightObserver.disconnect();
}
}
},[]);
Run Code Online (Sandbox Code Playgroud)
在我的尝试和错误中,对我不起作用的是以下内容。
这将导致“el 不存在”错误:
...
return () => {
heightObserver.unobserve(el);
}
...
Run Code Online (Sandbox Code Playgroud)
我可以对此进行测试,但这会导致内存泄漏:
...
return () => {
if(el){
heightObserver.unobserve(el);
}
}
...
Run Code Online (Sandbox Code Playgroud)
然后我发现.disconnect(),虽然没有浏览器问题,但不幸的是,所需的行为仅通过以下方式停止运行:
...
return () => {
heightObserver.disconnect();
}
...
Run Code Online (Sandbox Code Playgroud)
这就是我的过程,希望对某人有所帮助。我仍然觉得可能有更好的方法来做我正在做的事情,但据我所知,这是可行的。