我想创建一个
WeakSet
,其中包含未 100% 包含在文档根(<html>
标签)的 CSS 布局范围内的所有元素。我需要它实时更新,而不会对浏览器性能造成巨大影响。
为了实现这一目标,我使用了 intersectionObserver API,如下所示,这将创建我的 WeakSet,其中包含我传递它时所期望的所有元素
document.querySelectorAll('body *')
我的问题是,当我想测试某个元素是否在我的 WeakSet 中时,我在 Safari 中得到了正确的答案。但是,当我使用 false
检查匹配元素时,Chrome
和FireFox
始终返回
overflowedElements.has(el)
这似乎是由于 Chrome/FireFox 通过 IntersectionObserverEntry: target 属性错误地创建了对该元素的单独引用,从而导致对同一元素存在两个不匹配的引用。
因此我想我的问题是如何才能便宜地将正确的元素引用放入我的 WeakSet 中,以便我可以在所有浏览器中匹配它们?
const options = {
root: document.documentElement,
rootMargin: '0px',
threshold: 1,
}
const overflowedElements = new WeakSet()
const callback = (entries) => {
entries.forEach((entry) => {
if (entry.intersectionRatio !== 1) {
overflowedElements.add(entry.target)
} else {
overflowedElements.delete(entry.target)
}
})
console.log('overflowedElements', overflowedElements)
}
const observer = new IntersectionObserver(callback, options)
export const observeOverflow = (nodeList) => {
nodeList.forEach((el) => {
observer.observe(el)
})
}
export const isOverflowed = (el) => overflowedElements.has(el)
如果其他人需要这样做,解决方法是使用
entry.target.toggleAttribute
,然后使用 document.querySelectorAll
创建 nodeList
而不是 weakSet
。就我而言,事实证明这更有用且性能更好。