1. 程式人生 > >vue中引入mousewheel事件及其相容性處理

vue中引入mousewheel事件及其相容性處理

    專案實現過程中需要對一個已經有縱向滾動條的table表格增加滑鼠滾輪(mousewheel)事件,方便檢視資料;其實現原理與我上一篇部落格中的拖動事件類似,利用模擬出來的同一個滾動條來實現,滾動條設定的要點在於:1、滾動條與滾動槽的高度比例 應該等於 內容區(動態變化)和可視區的高度比例;滾動槽與可視區平齊,高度一樣,;滾動條的高度則根據內容的高度等比例計算;2、各元素的定位採用絕對定位,其父元素採用相對定位,這樣就能很好地設定樣式;

   佈局與樣式做好後,只需要在元件methods註冊方法,在元素就位後呼叫該方法,在方法內部為表格繫結(mousewheel)事件;在這裡需要考慮相容性問題,firefox並不支援mousewheel事件,它對應的滑鼠滾動事件為DOMMouseScroll事件,並且該事件僅能通過DOM2級(addEventListener)新增處理程式;

並且判斷滑鼠滾動方向的方式也不一樣,firefoxt通過detail屬性判斷,向前滾動該屬性為-3,向後+3;其餘瀏覽器通過wheelDelta屬性,向前時為+120的倍數,向後為-120的倍數;具體內容可參考《js高階程式設計》事件一章;加函式如下:

    scroll(){
        this.wrapDiv = document.getElementById("wrap");
        this.contentDiv = document.getElementById("context-table");
        this.contentDiv1 = document.getElementById("context-table1");
        this.sliderWrap = document.getElementById("sliderWrap");
        this.slider = document.getElementById("slider");
        //設定比例
        let scale =  this.wrapDiv.clientHeight /  this.contentDiv.clientHeight;
        if (scale < 1) {
          this.mouseFlag = true;
          let h1 =  this.sliderWrap.clientHeight * scale;
          h1 = (h1 < 50) ? 50 : h1;
          this.slider.style.height = h1 + "px";/*滾動條高度動態變化*/
          let y = 0;
          let that = this;
          //為firefox新增滾輪事件
          if (document.addEventListener){
            document.addEventListener('DOMMouseScroll',function (e) {
                if(that.mouseFlag){
                  //console.log('scroll');
                  let event1 = window.event|| e;
                  y = (event1.detail > 0) ? y + 8 : y - 8;
                  y = (y < 0) ? 0 : y;
                  let max = that.sliderWrap.clientHeight - that.slider.clientHeight;
                  y = (y > max + 1) ? max + 1 : y;
                  that.slider.style.top = y + "px";
                  scale = that.wrapDiv.clientHeight / that.contentDiv.clientHeight;
                  let y1 = -y / scale;
                  that.contentDiv.style.top = y1 + "px";
                  that.contentDiv1.style.top = y1 + "px";
                }
            },false)
          }
          this.wrapDiv.onmousewheel = function (e) {
            if (scale < 1) {
              let event1 = window.event || e;
              y = (event1.wheelDelta < 0) ? y + 8 : y - 8;
              y = (y < 0) ? 0 : y;/*限定滾動範圍*/
              let max =  that.sliderWrap.clientHeight -  that.slider.clientHeight;
              //console.log(scale, y, sliderWrap.clientHeight, slider.clientHeight);
              y = (y > max + 1) ? max + 1 : y;
              that.slider.style.top = y + "px";
              scale =  that.wrapDiv.clientHeight /  that.contentDiv.clientHeight;
              let y1 = -y / scale;
              that.contentDiv.style.top = y1 + "px";
              that.contentDiv1.style.top = y1 + "px";
            }
          }
        }
        else{/*當內容區高度小於等於可視區時,去除繫結的事件和滾動條*/
          this.wrapDiv.onmousewheel =null;
          if(document.addEventListener){
             this.mouseFlag = false;
          }
          this.sliderWrap.style.visibility = 'hidden';
          let height = this.contentDiv.clientHeight;
          tableRight.style.height  = height+72+'px';
          this.wrapDiv.style.height = height+2+'px';
        }
      },

      該函式在給firefox繫結的事件解綁時遇到了問題,由於removeEventListener()需要通過控制代碼來解綁,而addEventListener()通過控制代碼新增處理函式會導致event引數無法傳遞的問題;即使在需要解綁時給document繫結空的處理函式也無法覆蓋前一個繫結函式;最後只好新增一個標誌,在需要解綁函式時改變標誌的值;在繫結函式中通過判斷該標誌的值來確定是否要做操作;

    通過上述方式即可很好地實現滑鼠滾動事件的效果,並不會有相容性的問題出現。

注:若僅僅是為表格繫結單一的滾動事件,則可以不顯示滾動條,甚至不設定滾動條;滾動條的作用僅僅是用來指示內容區滾動的位置,以及配合拖動事件使用;