Skip to content

wheel事件和scroll事件的深入理解 🔍 ​

背景介绍 📝 ​

在开发一个水平滚动组件(XScroll)时,遇到了一个有趣的问题:笔记本触控板的双指滚动表现异常。这个问题引发了对wheel事件和scroll事件的深入研究。

问题描述 ❓ ​

  • 组件通过transform将垂直布局转换为水平展示
  • 鼠标滚轮上下滚动时可以正常实现视觉上的左右滑动
  • 但触控板双指左右滑动无法实现预期效果,必须上下滑动才能触发

wheel事件详解 🎡 ​

触发场景 ​

  • 🖱️ 鼠标滚轮滚动
  • 📱 触控板双指滑动
  • ⌨️ 键盘PageUp/PageDown/Home/End按键
  • 📲 触控笔和触摸屏滑动手势

重要属性 ​

javascript
event.deltaX    // 水平方向滚动距离
event.deltaY    // 垂直方向滚动距离
event.deltaZ    // Z轴方向滚动距离
event.deltaMode // 滚动单位(0:像素, 1:行, 2:页)

设备差异 ⚠️ ​

  1. 鼠标滚轮:

    • 主要改变deltaY
    • 单次触发值较大(约150)
    • 触发频率相对较低
  2. 触控板:

    • 双指左右滑动改变deltaX
    • 双指上下滑动改变deltaY
    • 触发值较小,但频率高

scroll事件详解 📜 ​

核心属性 ​

javascript
element.scrollTop    // 垂直滚动位置
element.scrollLeft   // 水平滚动位置
element.scrollHeight // 内容完整高度
element.scrollWidth  // 内容完整宽度

性能注意事项 ⚡ ​

scroll事件触发频率极高,建议使用节流(throttle)或防抖(debounce)进行性能优化。

两者关系与实践建议 🔗 ​

触发顺序 ​

通常wheel事件先于scroll事件触发,但在不同浏览器中可能有差异。

常见问题 ​

❌ 错误示例:直接使用deltaY

javascript
box.addEventListener('wheel', (e) => {
    e.currentTarget.scrollLeft += e.deltaY;  // 会造成卡顿
});

✅ 优化示例:

javascript
box.addEventListener('wheel', (e) => {
    e.preventDefault();
    const delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? e.deltaX : e.deltaY;
    e.currentTarget.scrollLeft += delta * 0.5;  // 添加平滑系数
});

注意事项 ​

  1. 在wheel事件中修改scrollTop/scrollLeft会阻止scroll事件触发
  2. 建议为滚动添加平滑效果:scroll-behavior: smooth
  3. 考虑不同设备的滚动特性,适当调整滚动系数

总结 📌 ​

理解wheel和scroll事件的区别和联系,对于开发更好的滚动交互体验至关重要。在实际应用中,需要考虑不同设备的特性,合理处理滚动行为,并注意性能优化。