鼠标滚轮(wheel)事件mac端优化指南

509 阅读1分钟

事件起因:测试小姐姐在测试表格时,发现表头不能使用mac的触摸板进行滑动,告诉我感知不到表格外面的滚动条,于是想在表头位置滑动下方的滚动条。

问题概述:OS端chrome在往左滚动时默认有个翻页事件,导致往右滑动时很顺畅,往左滚动时卡顿

image.png

解决方案:在监听的wheel事件中,阻止默认行为e.preventDefault();

技巧:计算wheel事件滑动距离,使用了 normalizeWheel这个插件的代码来计算。

  const PIXEL_STEP = 10;
  const LINE_HEIGHT = 40;
  const PAGE_HEIGHT = 800;
  // spinX, spinY
  let sX = 0;
  let sY = 0;
  // pixelX, pixelY
  let pX = 0;
  let pY = 0;
  // Legacy
  if ("detail" in event) {
    sY = event.detail;
  }
  if ("wheelDelta" in event) {
    sY = -event.wheelDelta / 120;
  }
  if ("wheelDeltaY" in event) {
    sY = -event.wheelDeltaY / 120;
  }
  if ("wheelDeltaX" in event) {
    sX = -event.wheelDeltaX / 120;
  }
  // side scrolling on FF with DOMMouseScroll
  if ("axis" in event && event.axis === event.HORIZONTAL_AXIS) {
    sX = sY;
    sY = 0;
  }
  pX = sX * PIXEL_STEP;
  pY = sY * PIXEL_STEP;
  if ("deltaY" in event) {
    pY = event.deltaY;
  }
  if ("deltaX" in event) {
    pX = event.deltaX;
  }
  if ((pX || pY) && event.deltaMode) {
    if (event.deltaMode === 1) {
      // delta in LINE units
      pX *= LINE_HEIGHT;
      pY *= LINE_HEIGHT;
    } else {
      // delta in PAGE units
      pX *= PAGE_HEIGHT;
      pY *= PAGE_HEIGHT;
    }
  }
  // Fall-back if spin cannot be determined
  if (pX && !sX) {
    sX = pX < 1 ? -1 : 1;
  }
  if (pY && !sY) {
    sY = pY < 1 ? -1 : 1;
  }
  return {
    spinX: sX,
    spinY: sY,
    pixelX: pX,
    pixelY: pY,
  };
}

总结:normalizeWheel这个插件里面还有一些关于滚轮事件的浏览器兼容性的代码没有细看,附上链接,有时间再来品味。

github.com/facebookarc…