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

如何在div滚动时或滚动结束后立即用原生JS检测鼠标位置

问题原因

scroll事件属于页面视图变动类事件,本身不携带鼠标坐标属性,所以直接从scroll事件对象中读取clientY/clientX必然返回undefined,只有鼠标交互类事件(如mousemove、mousedown等)的事件对象才会携带坐标属性。

优化实现方案

按照你只需要滚动触发时、滚动结束时获取鼠标坐标的需求,我们可以采用「滚动期间临时监听mousemove,滚动结束后立即移除监听」的逻辑,避免全局持续监听mousemove造成的性能浪费,原生实现代码如下:

完整实现代码

HTML

<div id="container">
  <div id="content"></div>
</div>
<div id="clientY_display">Scroll to see event.clientY position.. </div>

CSS

#container {
  height: 50px;
}

#content {
  height: 1000px;
  background-color: rgba(120,120,120,1);
}

#clientY_display {
  position: fixed;
}

JS

const clientYDisplay = document.getElementById("clientY_display");
// 存储最新鼠标坐标
let mousePos = { x: 0, y: 0 };
// 防抖计时器
let scrollTimer = null;
// 标记是否已经绑定了mousemove监听,避免重复绑定
let isListeningMouse = false;

// 鼠标移动监听函数
const handleMouseMove = e => {
  mousePos.x = e.clientX;
  mousePos.y = e.clientY;
  // 滚动过程中可以实时更新坐标,如果不需要可以删掉下一行,只在滚动结束更新
  clientYDisplay.textContent = `滚动中坐标:clientY = ${mousePos.y}, clientX = ${mousePos.x}`;
};

// 滚动监听函数
const handleScroll = () => {
  // 滚动触发时如果还没绑定鼠标监听就绑定
  if (!isListeningMouse) {
    document.addEventListener('mousemove', handleMouseMove);
    isListeningMouse = true;
  }

  // 防抖判断滚动结束:150ms内没有新的滚动事件就判定为滚动结束
  clearTimeout(scrollTimer);
  scrollTimer = setTimeout(() => {
    // 滚动结束后移除鼠标监听,避免不必要的性能消耗
    document.removeEventListener('mousemove', handleMouseMove);
    isListeningMouse = false;
    // 输出滚动结束时的最终坐标
    clientYDisplay.textContent = `滚动结束坐标:clientY = ${mousePos.y}, clientX = ${mousePos.x}`;
  }, 150);
};

document.addEventListener('scroll', handleScroll);
方案说明
  • 只有滚动触发后的150ms内会临时监听mousemove事件,页面无滚动时不会执行任何多余的监听逻辑,性能开销极低
  • 可以自行调整防抖的150ms参数,数值越大滚动结束判定越宽松,越小越敏感
  • 如果不需要滚动过程中实时更新坐标,只需要滚动结束后的结果,删掉handleMouseMove里的实时更新行即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:09:01