vue點選、滑動和長按等事件處理(自定義指令)
阿新 • • 發佈:2018-12-14
將以下程式碼封裝在一個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;
}
},