1. 程式人生 > >vue點選、滑動和長按等事件處理(自定義指令)

vue點選、滑動和長按等事件處理(自定義指令)

將以下程式碼封裝在一個js檔案裡,註釋很詳細,就不解釋了

import Vue from 'vue';

/**
 * @param el 繫結的DOM
 * @param binding 自定義指令中的binding物件
 * @param type 繫結的事件型別
 */
// 建構函式
function vueTouch(el,binding,type){
  var _this=this;
  this.obj=el; 
  this.binding=binding;
  this.touchType=type;
  this.vueTouches={x:0,y:0};//觸屏座標
  this.firstTouchTime = 0;
  /**
   * =========================================
   * 事件繫結有兩種方式
   * @example
   *  1. v-tap="showDialog" 繫結一個方法物件
   *  2. v-tap="{fn:click123, param1:1, param2:2, param3:{aaa:'123'} ...}"
   *      繫結一個JSON字面量,fn是執行的方法,後邊的是需要傳遞的引數
   * 事件回撥引數
   * @param 第一個引數是event,事件物件
   * @param 第二個引數是 binding.value,也就是v-tap=""雙引號中的部分(如示例2,第二個引數就是 {fn:click123, param1:1, param2:2, param3:{aaa:'123'} ...})
   * =========================================
   */
  this.vueCallBack=typeof(binding.value)=="object"?binding.value.fn:binding.value;
  // 事件回撥
  this.obj.addEventListener("touchstart",function(e){
    _this.start(e);
  },false);
  this.obj.addEventListener("touchend",function(e){
    _this.end(e);
  },false);
  this.obj.addEventListener("touchmove",function(e){
    _this.move(e);
  },false);
};
vueTouch.prototype={
  //監聽touchstart事件
  start:function(e){
    this.vueMoves=false;
    this.vueLeave=false;
    this.longTouch=false;
    // 獲取開始點選位置和時間
    this.vueTouches={x:e.changedTouches[0].pageX,y:e.changedTouches[0].pageY};
    this.firstTouchTime = e.timeStamp;
  // 判斷長按操作
    this.time=setTimeout(function(){
      if(!this.vueLeave && !this.vueMoves){
        this.touchType=="longtap"&&this.vueCallBack(this.binding.value,e);
        this.longTouch=true;
      };
    }.bind(this),1000);
  },
  //監聽touchend事件
  end:function(e){
    // 計算位移和時差
    var disX=e.changedTouches[0].pageX-this.vueTouches.x;
    var disY=e.changedTouches[0].pageY-this.vueTouches.y;
    let _timeDis = e.timeStamp - this.firstTouchTime;
    clearTimeout(this.time);
    // 判斷滑動事件
    if(Math.abs(disX)>10||Math.abs(disY)>100){
      this.touchType=="swipe"&&this.vueCallBack(this.binding.value,e);
      if(Math.abs(disX)>Math.abs(disY)){
        if(disX>10){
          this.touchType=="swiperight"&&this.vueCallBack(this.binding.value,e);//右滑
        };
        if(disX<-10){
          this.touchType=="swipeleft"&&this.vueCallBack(this.binding.value,e);//左滑
        };
      }else{
        if(disY>10){
          this.touchType=="swipedown"&&this.vueCallBack(this.binding.value,e);//下滑
        };
        if(disY<-10){
          this.touchType=="swipeup"&&this.vueCallBack(this.binding.value,e);//上滑
        };
      };
    }else{
      // 點選事件
      if(!this.longTouch && !this.vueMoves){
        this.touchType=="tap"&&this.vueCallBack(this.binding.value,e);
      };
    };
  },
  // 監聽touchmove事件
  move:function(e){
    this.vueMoves=true;
  }
};
Vue.directive("tap",{//點選事件
  bind:function(el,binding){
    new vueTouch(el,binding,"tap");
  }
});
Vue.directive("swipe",{//滑動事件
  bind:function(el,binding){
    new vueTouch(el,binding,"swipe");
  }
});
Vue.directive("swipeleft",{//左滑事件
  bind:function(el,binding){
    new vueTouch(el,binding,"swipeleft");
  }
});
Vue.directive("swiperight",{//右滑事件
  bind:function(el,binding){
    new vueTouch(el,binding,"swiperight");
  }
});
Vue.directive("swipedown",{//下滑事件
  bind:function(el,binding){
    new vueTouch(el,binding,"swipedown");
  }
});
Vue.directive("swipeup",{//上滑事件
  bind:function(el,binding){
    new vueTouch(el,binding,"swipeup");
  }
});
Vue.directive("longtap",{//長按事件
  bind:function(el,binding){
    new vueTouch(el,binding,"longtap");
  }
});

使用:在需要的頁面引入這個js檔案 

import touch from '@/utils/touch';

以物件的形式傳值fn是執行的函式,之後為引數,引數不需要可不傳

      <div style="height: 200px;border: 1px solid #ccc;"
             v-tap="{fn:vuetouch,name:'點選'}"
        v-longtap="{fn:vuetouch,name:'長按'}"
        v-swipeleft="{fn:vuetouch,name:'左滑'}"
        v-swiperight="{fn:vuetouch,name:'右滑'}"
        v-swipeup="{fn:vuetouch,name:'上滑'}"
        v-swipedown="{fn:vuetouch,name:'下滑'}"
        >{{name}}</div>
    data() {
      return {
        name:"開始"
      };
    },
    methods: {
      vuetouch:function(s,e){
        this.name=s.name;
      }
    },