代码改变世界

学习 JS滚轮事件(mousewheel/DOMMouseScroll)

  龙恩0707  阅读(2925)  评论(0编辑  收藏  举报

学习 JS滚轮事件(mousewheel/DOMMouseScroll)

1-1 滚轮事件兼容性的差异
   IE,chrome,safari 浏览器都使用 onmousewheel, 只有firefox浏览器使用 DOMMouseScroll 事件,一个最简单的测试demo如下:
HTML代码如下:

<div style="height:2000px"></div>
页面滚动条滚动的时候,使用js去监听事件如下:

复制代码
document.body.onmousewheel = function(event) {
  event = event || window.event;
  console.log(11)
  console.log(event);
}

document.body.addEventListener('DOMMouseScroll', function(event) {
  console.log(222);
  console.log(event);
});
复制代码

上面代码可以看到,safari和chrome都使用 onmousewheel 事件监听,只有firefox使用 DOMMouseScroll 事件监听。

下面我们来看看 safari,chrome和firefox 浏览器各个属性差异性如下:

复制代码
属性名:              Firefox              chrome                     safari
type                 DOMMouseScroll       mousewheel                 mousewheel
formElement          没有该属性             null                      null
toElement            没有该属性            [object HTMLDivElement]   [object HTMLDivElement] 
wheelDelta           没有该属性            -120(向下滚动)              -12(向下滚动)
srcElement           没有该属性            [object HTMLDivElement]   [object HTMLDivElement]
screenX              353                  406                       872
screenY              278                  284                       281
clientX              353                  406                       629 
clientY              140                  164                       219
offsetX              0                    398                       621
offsetY              0                    200                       211
layerX               353                  406                       629
layerY               140                  208                       219
pageX                353                  406                       629
pageY                140                  208                       219
which                1                    0                          1
detail               1                    0                          0
currentTarget        null                 null                      null
target         [object HTMLDivElement]    [object HTMLDivElement]   [object HTMLDivElement]
wheelDeltaY         没有该属性              -120                       -12
wheelDeltaX         没有该属性              0                           0
returnValue         没有该属性              true                        true
preventDefault      没有该属性              没有该属性                    没有该属性
复制代码

注意(目前测试使用的是Mac系统,window系统好久没有使用过了~)
如上的一些属性对比,可以看到,除了firefox以外,chrome上下滚动式使用 wheelDelta(向下滚动,该值为-120,向上滚动该值为120);safari上下滚动也使用 wheelDelta(向下滚动,该值为-12,向上滚动该值为12),对于firefox浏览器或 Opera浏览器而言,判断鼠标滚动方向的属性为 event.detail, 向下滚动为1,向上滚动为-1;

注意:safari滚动一圈的话(向下滚动值为-12,向上滚动值为12,但是如果滚动稍微快点的话,会多滚动几圈,那么该值即将变大,滚动几圈,那么就是 -12 * 几圈)。

1-2 兼容滚轮事件的方法
知道上面的一些差异后,我们现在可以封装一个兼容 safari,chrome和firefox的函数了;代码如下:

复制代码
var addEvent = (function(window, undefined) {
  var _event = function(event) {
    var type = event.type;
    if (type === 'DOMMouseScroll' || type === 'mousewheel') {
      console.log(event)
      event.delta = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0);
    }
    if (event.srcElement && !event.target) {
      event.target = event.srcElement;
    }
    if (!event.preventDefault && event.returnValue !== undefined) {
      event.preventDefault = function() {
        event.returnValue = false;
      }
    }
    return event;
  };
  if (window.addEventListener) {
    return function(el, type, fn, capture) {
      if (type === 'mousewheel' && document.mozFullScreen !== undefined) {
        type = "DOMMouseScroll";
      }
      el.addEventListener(type, function(event) {
        fn.call(this, _event(event));
      }, capture || false);
    }
  } else if (window.attachEvent) {
    return function(el, type, fn, capture) {
      el.attachEvent("on" + type, function(event) {
        event = event || window.event;
        fn.call(el, _event(event));
      });
    }
  }
})(window);
复制代码

测试使用方法如下:

addEvent(window, "mousewheel", function(event) {
  console.log(event.delta);
  if(event.delta < 0) {
    console.log('鼠标向下滚动了');
  }
});
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示