无需移除EventListener,如何让其仅触发一次?(无jQuery)
解决滚动事件重复添加class的问题
嘿,这个问题我太熟了!滚动事件本身就会非常频繁地触发,你当前的代码每次满足yPosition >= 5的条件就直接拼接className,自然会把shorter类重复添加多次,导致HTML里的class属性变得乱糟糟。给你几个简单又靠谱的解决办法:
方法1:用classList.add替代直接拼接className
这是最直接的修复方式,classList.add方法本身就会自动判断——如果目标类已经存在,它不会重复添加。修改后的代码如下:
window.addEventListener("scroll", sHeader); function sHeader(){ var yPosition = window.pageYOffset; if ( yPosition >= 5 ){ header.classList.add('shorter'); // 替换原来的className拼接 } }
如果还需要在滚动回顶部(yPosition < 5)时移除这个类,可以补充else逻辑:
else { header.classList.remove('shorter'); }
方法2:先检查类是否存在再添加(兼容旧场景)
如果出于某些原因不想用classList(比如兼容非常老旧的浏览器,不过现在几乎不需要考虑了),可以手动判断类是否存在:
window.addEventListener("scroll", sHeader); function sHeader(){ var yPosition = window.pageYOffset; // 先判断是否已有shorter类,没有才添加 if ( yPosition >= 5 && !header.classList.contains('shorter') ){ header.className += ' shorter'; } }
不过还是更推荐方法1,代码更简洁且语义化。
方法3:优化滚动事件触发频率(可选但推荐)
滚动事件触发得太频繁,哪怕修复了类的问题,也可能造成不必要的性能消耗。可以用防抖函数来减少触发次数,同时结合classList.toggle的条件写法让代码更精简:
// 防抖函数:指定时间内只执行一次目标函数 function debounce(func, delay) { let timer; return function() { clearTimeout(timer); timer = setTimeout(func, delay); } } // 用防抖后的函数绑定滚动事件 window.addEventListener("scroll", debounce(sHeader, 100)); function sHeader(){ var yPosition = window.pageYOffset; // toggle的第二个参数:为true时添加类,为false时移除 header.classList.toggle('shorter', yPosition >= 5); }
这里的100是延迟毫秒数,可以根据需求调整,比如改成50会更灵敏,改成200会更节省性能。
内容的提问来源于stack exchange,提问作者KAindex
相关产品推荐
相关产品推荐

