You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需移除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:04:12