首页 » 技术分享 » vue自定义移动端touch事件,点击、滑动、长按事件

vue自定义移动端touch事件,点击、滑动、长按事件

 

用法:

**HTML**
<div class="box" 
    v-tap="(e)=>vueTouch('点击',e)" 
    v-longtap="(e)=>vueTouch('长按',e)" 
    v-swipeleft="(e)=>vueTouch('左滑',e)"
    v-swiperight="(e)=>vueTouch('右滑',e)"
    v-swipeup="(e)=>vueTouch('上滑',e)"
    v-swipedown="(e)=>vueTouch('下滑',e)"
 >{{ 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更新
https://github.com/904790204/vue-touch

最近一直在忙,最新的用法已经更新,可以直接从npm下载安装kim-vue-touch,传参方式也做了修改,有什么问题可以直接联系我,qq:904790204

转载自原文链接, 如需删除请联系管理员。

原文链接:vue自定义移动端touch事件,点击、滑动、长按事件,转载请注明来源!

0