欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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事件之点击、滑动、长按事件,希望对大家有所帮助