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

JavaScript scroll事件监听致scrollY波动、滚动条故障求助

问题排查与修复:scroll事件中scrollY波动、滚动条故障

核心原因分析

你遇到的scrollY值波动、滚动条故障,本质是scroll事件中修改元素高度导致页面总高度动态变化,触发了循环scroll事件:

  • 你的.square元素是position: relative,修改它的height会直接改变父容器.demo-wrapper的高度,进而影响整个页面的总高度
  • 页面高度变化会强制浏览器重新计算滚动位置,再次触发scroll事件,形成恶性循环,最终导致scrollY值来回跳动、滚动条异常

另外还有几个次要问题放大了异常:

  • 箭头函数中this.scrollY的this不指向window,应该直接用window.scrollY
  • 代码中使用了未定义的modulus函数,应该替换为Math.abs来计算绝对值
  • scroll事件触发频率极高,没有做节流处理,加剧了性能问题和异常波动

修复方案

1. 脱离文档流,避免修改元素高度影响页面布局

将.square的定位改为fixed(或absolute,根据需求调整),这样修改高度不会影响页面总高度:

.square{
  position: fixed; /* 替换relative为fixed */
  width:20px;
  height:20px;
  left: 50%; /* 配合fixed实现水平居中 */
  transform: translateX(-50%);
  background-color:#DC3F0A ;
}

2. 修正scrollY获取方式与未定义函数

把箭头函数中的this.scrollY改为window.scrollY,并用Math.abs替代modulus:

window.addEventListener('scroll',(event)=>{
  let scroll = window.scrollY; // 修正this指向问题
  console.log(scroll)
  let div
  let rate
  for(let j=0;j<3;j++){
    div = document.getElementById(`sq${j}`)
    let { top: t } = div.getBoundingClientRect();
    const diff = Math.abs(scroll - t); // 替换modulus为Math.abs
    rate=(400-diff)/4
    rate*=2
    rate-=(rate)/4
    if(diff <=400 && rate>20){
      div.style.height = `${rate}px`;
    } else {
      div.style.height = "20px";
    }
  }
})

3. 添加节流函数,降低scroll事件触发频率

scroll事件每秒会触发数十次,添加节流可以减少不必要的计算,优化性能:

// 节流函数
function throttle(func, delay = 16) {
  let timer = null;
  return function(...args) {
    if (!timer) {
      timer = setTimeout(() => {
        func.apply(this, args);
        timer = null;
      }, delay);
    }
  };
}

// 用节流包装scroll事件回调
window.addEventListener('scroll', throttle((event)=>{
  // 原回调逻辑...
}));

4. 优化初始元素创建逻辑

可以简化元素创建的代码,同时避免重复查询DOM:

const demoWrapper = document.querySelector(".demo-wrapper");
for(let i=0;i<3;i++){
  const temp = document.createElement('div')
  temp.id=`sq${i}`
  temp.classList.add('square', 'new')
  temp.style.top=`${100 + (i*5)}px`
  demoWrapper.appendChild(temp)
}

完整修正后的代码

JavaScript

// 节流函数
function throttle(func, delay = 16) {
  let timer = null;
  return function(...args) {
    if (!timer) {
      timer = setTimeout(() => {
        func.apply(this, args);
        timer = null;
      }, delay);
    }
  };
}

// 创建元素
const demoWrapper = document.querySelector(".demo-wrapper");
for(let i=0;i<3;i++){
  const temp = document.createElement('div')
  temp.id=`sq${i}`
  temp.classList.add('square', 'new')
  temp.style.top=`${100 + (i*5)}px`
  demoWrapper.appendChild(temp)
}

// 监听scroll事件(带节流)
window.addEventListener('scroll', throttle((event)=>{
  let scroll = window.scrollY;
  console.log(scroll)
  for(let j=0;j<3;j++){
    const div = document.getElementById(`sq${j}`)
    const { top: t } = div.getBoundingClientRect();
    const diff = Math.abs(scroll - t);
    let rate=(400-diff)/4
    rate*=2
    rate-=(rate)/4
    if(diff <=400 && rate>20){
      div.style.height = `${rate}px`;
    } else {
      div.style.height = "20px";
    }
  }
}));

CSS

.square{
  position: fixed;
  width:20px;
  height:20px;
  left: 50%;
  transform: translateX(-50%);
  background-color:#DC3F0A ;
}
body{
  overflow: scroll;
  background-color: #353433;
}
html{
  height:200%;
}
.new:hover{
  background-color:white;
}

HTML(无需修改)

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>hey man this is my page</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
  <link href="style.css" rel="stylesheet" type="text/css" />
</head>

<body>
  <div class="demo-wrapper ">
  </div>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN"
    crossorigin="anonymous"></script>
  <script src="https://replit.com/public/js/replit-badge.js" theme="blue" defer></script>
  <script src="script.js"></script>
</body>
</html>

内容的提问来源于stack exchange,提问作者shehzail abbas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:17:07