vue自定义移动端touch事件之点击、滑动、长按事件
程序员文章站
2022-03-07 08:28:46
用法:
**html**
用法:
**html** <div id="app" class="box" v-tap="vuetouch" //vuetouch为函数名,如没有参数,可直接写函数名 v-longtap="{fn:vuetouch,name:'长按'}" //如果有参数以对象形式传,fn 为函数名 v-swipeleft="{fn:vuetouch,name:'左滑'}" v-swiperight="{fn:vuetouch,name:'右滑'}" v-swipeup="{fn:vuetouch,name:'上滑'}" v-swipedown="{fn:vuetouch,name:'下滑'}" >{{ name }}</div> **js** kim=new vue({ el:"#app", data:{ name:"开始" }, methods:{ vuetouch:function(s,e){ this.name=s.name; } } });
js核心内容
function vuetouch(el,binding,type){ var _this=this; this.obj=el; this.binding=binding; this.touchtype=type; this.vuetouches={x:0,y:0}; this.vuemoves=true; this.vueleave=true; this.longtouch=true; 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={ start:function(e){ this.vuemoves=true; this.vueleave=true; this.longtouch=true; this.vuetouches={x:e.changedtouches[0].pagex,y:e.changedtouches[0].pagey}; this.time=settimeout(function(){ if(this.vueleave&&this.vuemoves){ this.touchtype=="longtap"&&this.vuecallback(this.binding.value,e); this.longtouch=false; }; }.bind(this),1000); }, end:function(e){ var disx=e.changedtouches[0].pagex-this.vuetouches.x; var disy=e.changedtouches[0].pagey-this.vuetouches.y; 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); this.vueleave=false }; }; }, move:function(e){ this.vuemoves=false; } }; 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"); } });
2018-03-08
有朋友提出一个bug
“v-for循环 生命周期后 获取不到新值 比如更新了数据”
这个问题是v-for的就地复用机制导致的,也就是可以复用的dom没有重复渲染,官方给出的方法是需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的且唯一的 id。
<div v-for="item in items" :key="item.id"> <!-- 内容 --> </div>
我的解决方案是directive的钩子函数参数有一个vnode,这个是虚拟dom节点,给vnode.key赋予一个随机id,强制dom刷新。
vue.directive("tap",{ bind:function(el,binding,vnode){ vnode.key = randomstring()//randomstring会返回一个随机字符串 new vuetouch(el,binding,"tap"); } });
最新的版本已经在github更新
总结
以上所述是小编给大家介绍的vue自定义移动端touch事件之点击、滑动、长按事件,希望对大家有所帮助