如何在IntersectionObserver的forEach中处理无条目满足条件的情况?
IntersectionObserver 无相交元素时执行操作的实现
问题描述
你现有一段使用IntersectionObserver实现元素高亮切换的代码,通过遍历观察到的section元素,在元素进入视口(entry.isIntersecting为true)时切换高亮状态。现在想在回调中添加逻辑:当所有被观察的元素都不处于相交状态时,执行其他操作。
原代码如下:
const sections = document.querySelectorAll("section") function removeHighlight(id) { someElementArray[id].classList.remove('highlight') } function addHighlight(id) { someElementArray[id].classList.add('highlight') } function onObserve(entries, observer) { entries.forEach((entry) => { if (entry.isIntersecting) { const { id } = entry.target removeHighlight(selectedId) addHighlight(id) selectedId = id } }) } const observer = new IntersectionObserver(onObserve, options) sections.forEach((section) => { observer.observe(section) })
你的需求是在onObserve回调中补充逻辑,当所有条目都不满足相交条件时执行额外操作:
function onObserve(entries, observer) { entries.forEach((entry) => { if (entry.isIntersecting) { const { id } = entry.target removeHighlight(selectedId) addHighlight(id) selectedId = id } }) // otherwise, if none of the items meet the condition // do something else }
解决方案
不能直接仅通过当前回调的entries判断,因为entries只包含状态发生变化的元素,并非所有被观察元素。我们需要维护一个全局变量跟踪当前处于相交状态的元素数量,再通过这个数量判断是否所有元素都不相交。
修改后的代码如下:
const sections = document.querySelectorAll("section") // 维护当前相交元素的数量 let intersectingCount = 0 let selectedId = '' function removeHighlight(id) { someElementArray[id].classList.remove('highlight') } function addHighlight(id) { someElementArray[id].classList.add('highlight') } function onObserve(entries, observer) { entries.forEach((entry) => { if (entry.isIntersecting) { // 元素进入视口,相交计数+1 intersectingCount++ const { id } = entry.target removeHighlight(selectedId) addHighlight(id) selectedId = id } else { // 元素离开视口,相交计数-1 intersectingCount-- } }) // 判断是否所有元素都不相交(计数为0) if (intersectingCount === 0) { // 执行你需要的操作,比如移除所有高亮、显示提示等 removeHighlight(selectedId) selectedId = '' // 其他操作示例:console.log('所有section都不在视口中') } } const observer = new IntersectionObserver(onObserve, options) sections.forEach((section) => { observer.observe(section) })
关键说明
intersectingCount变量用于实时统计当前处于相交状态的元素数量,元素进入视口时递增,离开时递减- 在遍历完
entries后,判断intersectingCount是否为0,即可确定是否所有被观察元素都不处于视口中 - 支持多个元素同时进入/离开视口的场景,计数会正确更新,确保判断准确
内容的提问来源于stack exchange,提问作者interwebjill
相关产品推荐
相关产品推荐

