多元素共用同一IntersectionObserver,如何正确为相交元素操作类?
IntersectionObserver操作元素类名问题排查与解决
我用IntersectionObserver监听多个元素时碰到个问题:entry.target.classList.add()不生效,但classList.remove()能正常工作。想知道怎么正确定位相交元素并执行类名的添加/移除操作,原代码如下:
let observerOptions = { rootMargin: '0px', threshold: 0.5 } var observer = new IntersectionObserver(observerCallback, observerOptions); function observerCallback(entries, observer) { entries.forEach(entry => { if(entry.isIntersecting) { //do something // want to do entry.target.classList.add('square-transition'); } // want to do entry.target.classList.remove('square-transition'); }); }; let target = '.targetSelector'; document.querySelectorAll(target).forEach((i) => { if (i) { observer.observe(i); } });
问题根源
你写的代码里,classList.remove()是在if(entry.isIntersecting)判断的外面——不管元素是否相交,都会执行移除操作。也就是说,当元素相交时,刚执行完add,立刻就被remove覆盖了,所以看不到添加类名的效果。
修正后的代码
把移除操作放到else分支里,只有当元素不相交时才执行:
let observerOptions = { rootMargin: '0px', threshold: 0.5 } var observer = new IntersectionObserver(observerCallback, observerOptions); function observerCallback(entries, observer) { entries.forEach(entry => { if(entry.isIntersecting) { // 元素相交时添加类名 entry.target.classList.add('square-transition'); } else { // 元素不相交时移除类名 entry.target.classList.remove('square-transition'); } }); }; let target = '.targetSelector'; document.querySelectorAll(target).forEach((i) => { if (i) { observer.observe(i); } });
额外排查点
如果修正后还是不行,可以检查这几点:
- 类名
square-transition是否拼写正确,有没有大小写错误 - 目标元素是否真的被正确监听(可以在回调里打印
entry.target确认) - CSS优先级问题:是不是其他更高优先级的样式覆盖了这个类的效果
内容的提问来源于stack exchange,提问作者Steve Goerger
相关产品推荐
相关产品推荐

