學習 JS滾輪事件(mousewheel/DOMMouseScroll)

龍恩0707發表於2017-08-15

學習 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('滑鼠向下滾動了');
  }
});

相關文章