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

DOM实现运动模糊效果仅在开启开发者工具时生效,关闭后失效问题求助

问题根因

你的现象是Chromium内核浏览器(包括你使用的OperaGX)的定时器合并优化导致的:

  • 未开启开发者工具时,浏览器会默认开启性能优化:所有小于4ms的setTimeout会被强制延迟到4ms执行,且时间接近的定时器任务会被合并到同一个渲染帧批量执行。你设置的delayedPromiseArray[i].vel是0~29ms的极短延迟,这些位置更新任务最后几乎同时执行,拖影的位置差就消失了。
  • 开启开发者工具时,浏览器为了保证调试时的时间精度,会默认关闭定时器合并优化,每个setTimeout都会按照你设置的延迟独立触发,所以能看到正常的拖影效果。

另外你的实现逻辑本身也存在缺陷:mousemove事件触发频率远高于60帧,每次触发都会注册30个定时器,会产生大量冗余任务,进一步加剧定时器合并的问题。

修复方案

不要依赖setTimeout的时间差实现拖影,改为维护鼠标坐标的历史队列,在独立的requestAnimationFrame渲染循环中,让不同透明度的圆点分别跟随不同时间点的历史坐标,完全规避定时器优化的影响。

修复后的代码

JavaScript

window.addEventListener('load', function (e) {
  const SAMPLES = 30; // 拖影采样数
  const MOTION_BLUR_STRENGTH = 2; // 拖影长度,可自行调整
  let autoAlpha = 1 / SAMPLES;
  // 鼠标坐标历史队列,初始值为屏幕中心
  let mouseHistory = new Array(SAMPLES).fill({x: window.innerWidth/2, y: window.innerHeight/2});

  // 样式定义
  let style = document.createElement('style');
  style.innerHTML = `
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
html{      
min-height: 100%;
height: 100%;
}
.mouseInjectionWrapper{
inset: 0;
position: fixed;
width: 100vw;
height: 100vh;
background-color: transparent;
}
.boxdivmouseinjected{
border-radius: 50%;
position: absolute;
border: 2px solid red;
width: 15px;
height: 15px;
background-color: #FFFFFF;
transform: translate(-50%, -50%);
}
`;
  document.head.appendChild(style);

  let wboxdiv = document.createElement('div');
  wboxdiv.classList.add('mouseInjectionWrapper');
  wboxdiv = document.body.appendChild(wboxdiv);

  // 生成拖影圆点
  let boxList = [];
  for (let i = 0; i < SAMPLES; i++) {
    let boxdiv = document.createElement('div');
    boxdiv.classList.add('boxdivmouseinjected');
    boxdiv.style.opacity = autoAlpha * (SAMPLES - i);
    wboxdiv.appendChild(boxdiv);
    boxList.push(boxdiv);
  }

  // 监听鼠标移动更新最新坐标
  window.addEventListener('mousemove', function (e) {
    // 把最新坐标放到队列头部
    mouseHistory.unshift({x: e.clientX, y: e.clientY});
    // 队列长度保持和采样数一致,避免内存溢出
    if(mouseHistory.length > SAMPLES) mouseHistory.pop();
  })

  // 独立渲染循环
  function render() {
    // 每个圆点对应历史队列里的对应位置坐标,间隔越大拖影越长
    boxList.forEach((box, index) => {
      const historyPos = mouseHistory[Math.min(index * MOTION_BLUR_STRENGTH, mouseHistory.length -1)];
      box.style.left = `${historyPos.x}px`;
      box.style.top = `${historyPos.y}px`;
    })
    requestAnimationFrame(render);
  }
  render();
});

HTML部分无需修改

验证说明

修复后的实现完全不依赖setTimeout,通过历史坐标队列直接控制拖影的位置差,不管是否开启开发者工具都能正常显示运动模糊效果,同时性能远高于原实现,不会产生大量冗余定时器任务。

内容的提问来源于stack exchange,提问作者Pedro Reinaldo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:18:04