一文讀懂鼠標滾輪事件(wheelEvent)

最近在用VUE寫一個後臺管理系統,頂部標籤頁涉及鼠標滾輪事件,因爲每一個瀏覽器對滾輪事件的處理方式不同,我的對這個又不懂,折騰了好久,參考了大神的代碼,也把百度翻爛了,找到了一篇陳舊的博文(實際上是主題很土,發佈時間未知)。寫得很是清楚,解決了個人問題。
先看看我標籤頁的界面:jquery

clipboard.png

若是打開的標籤超過滾動區域寬度,會顯示滾動條,支持鼠標滾輪左右滾動。這裏涉及wheelEvent的2個屬性:wheelDelta 和 deltaY,後面轉載的博文會詳細測試。
首先在MDN網站看到了官方概念:算法

clipboard.png

這裏得到2個信息:
①傳統的mousewheel事件已經充用,請使用wheel事件。
②不要經過判斷滾輪方向來推斷文檔滾動方向。
下面正式推薦大神的博文:canvas

前段時間使用canvas作滾動條控件,添加滾輪事件時,查閱了一些資料,發現大都是文檔描述或簡單示例,對於開發者仍是不夠。wheelEvent對象中的一些屬性(好比wheelDelta、detail等)雖然官方文檔有完整描述,但部分或大部分瀏覽器廠商並無(真正)實現,這就很容易誘導你們錯誤使用。因此我針對當前經常使用瀏覽器從新測試了一下。

1、測試目標

探索wheelEvent事件中經常使用屬性的有效性,垂直步進算法(滑動幅度)以及與電腦個性化設置的關聯。瀏覽器

2、測試環境

Windows操做系統,Firefox5四、Chrome5九、IE九、IE十、IE十一、Edge瀏覽器。網絡

3、測試屬性

deltaY、detail、wheelDeltaapp

電腦個性化設置:操做系統鼠標滑輪垂直行數n(默認值:3)測試

輔助關聯參數:瀏覽器窗口高度H用來驗證deltaY的推導公式網站

測試代碼:this

var onwheel = function(e){
     var _log = "",
         _ie9 = navigator.userAgent.indexOf("MSIE 9.0") > 0,
         _h = _ie9 ? window.innerHeight : document.body.clientHeight;  //兼容IE9

     _log += "deltaY:" + e.deltaY;
     _log += "|wheelDelta:" + e.wheelDelta;
     _log += "|detail:" + e.detail;   
     _log += "|H:" + _h;

   console.log(_log);
};

document.addEventListener("wheel", onwheel, false);

測試結果:spa

clipboard.png

4、結果分析

一、Firefox有效屬性deltaY,正值向下滾動,絕對值爲操做系統鼠標滑輪垂直行數設置;

二、IE系列有效屬性deltaY,正值向下滾動,絕對值爲滾動幅度(像素數,計算方式:窗口高度×鼠標滾輪垂直行數÷20)

三、Edge有效屬性deltaY,同IE系列,而且支持wheelDelta屬性(向上120,向下-120,但爲常量,只能判斷方向,與滾輪速率無關,有種被欺騙的感受。。。)

四、Chrome有效屬性deltaY,正值向下滾動,絕對值爲滾動幅度(像素數,計算方式:100×鼠標滾輪垂直行數÷3)而且支持wheelDelta,與Edge同樣,也是假值;

五、測試的幾款瀏覽器deltaY都與操做系統鼠標滾輪垂直行數正相關;

六、IE系列與Edge瀏覽器deltaY與瀏覽器窗口高度相關(瀏覽器以當前窗口可容20行,來動態計算行高),Chrome與窗口高度無關;

5、結論

一、可靠屬性:deltaY,方向判斷方法一致(正值向下滾動,負值向上滾動),與操做系統鼠標設置有關聯,但需注意絕對值算法不統一

二、無用屬性:detail,wheelDelta(未實現,即便Chrome與Edge也是假值,這與mdn、w3c等文檔描述有差別,但看網絡相關分享、jquery控件等卻發現不少人都在使用。。。)

三、功能方面:Firefox能直觀反映滾動行數,但不能直觀與瀏覽器默認滾動條保持同步;其餘幾組瀏覽器則剛好相反;

四、我的建議:我的認爲wheelDelta的最初設計思想很好,電腦鼠標滾輪垂直行數默認值是3,wheelDelta默認值120,即單行行高40px,即便用戶電腦作了個性化設置,像素值也不會出現循環小數,避免了Chrome的deltaY設計缺陷,有利於行業規範化,因此建議各瀏覽器廠商能完整支持wheelDelta這一屬性。

6、應用領域

滾動條控件滾輪事件設計:滾輪效果應該有效使用電腦個性化設置

方案1、固定步距(滾動幅度):按推導公式計算鼠標滾動行數n值,設定固定行高H,幅度=n×H

方案2、嵌入式(與瀏覽器默認效果同步):Firefox使用body字號做爲行高H,幅度=deltaY×H;其餘瀏覽器,幅度=deltaY

7、VUE中的實踐

下面是代碼,自行參考:

<template>
  <el-scrollbar
    ref="scrollContainer"
    :vertical="false"
    class="scroll-container"
    @wheel.native.prevent="handleScroll"
  >
    <slot/>
  </el-scrollbar>
</template>

<script>
export default {
  name: "ScrollPane",
  data() {
    return {
      left: 0
    };
  },
  methods: {
    handleScroll(e) {
      // wheelDelta:獲取滾輪滾動方向,向上120,向下-120,但爲常量,與滾輪速率無關
      // deltaY:垂直滾動幅度,正值向下滾動。電腦鼠標滾輪垂直行數默認值是3
      // wheelDelta只有部分瀏覽器支持,deltaY幾乎全部瀏覽器都支持
      const eventDelta = e.wheelDelta || -e.deltaY * 40;
      const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap;
      // 0到scrollLeft爲滾動區域隱藏部分
      $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4;
    }
  }
};
</script>
相關文章
相關標籤/搜索