Vue指令可拖动元素,兼容PC和移动端

Vue.directive('movable',{
  bind(el){
    let agent=window.navigator.userAgent.toLowerCase(),start,move,end
    //判断当前是移动端还是PC,移动端监听touch,PC监听mouse
    if(["android","iphone","symbianos","windows phone","ipad","ipod"].some(i=>agent.indexOf(i)>0)){ start='touchstart';move='touchmove';end='touchend' }else{ start='mousedown';move='mousemove';end='mouseup' }
    //添加事件开始监听
    el.addEventListener(start,e=>{
      //读取事件开始时,触摸或鼠标按下的坐标,以及容器当前所在位置,并声明两个函数对象,供后面添加和取消监听用
      let cur=e.touches?{x:e.touches[0].clientX,y:e.touches[0].clientY}:{x:e.clientX,y:e.clientY},x=el.offsetLeft,y=el.offsetTop,prevent=function(){event.preventDefault()},moveFun=function(){
        if(event.touches){
          el.style.left=event.touches[0].clientX-cur.x+x+'px'
          el.style.top=event.touches[0].clientY-cur.y+y+'px'
        }else{
          el.style.left=event.clientX-cur.x+x+'px'
          el.style.top=event.clientY-cur.y+y+'px'
        }
        //阻止移动端屏幕移动
        window.addEventListener('touchmove',prevent,{passive:false})
      }
      //监听move并修改位置
      el.addEventListener(move,moveFun)
      //声明一个移除处理函数对象
      let endFun=function(){
        el.removeEventListener(move,moveFun)
        el.removeEventListener(move,endFun)
        window.removeEventListener('touchmove',prevent)
      }
      //监听到事件结束时,移除start以外的监听
      el.addEventListener(end,endFun)
    })
  }
})

新手注意事项:

  1. 此处假设的是容器采用了fixed或absolute定位,然后修改left和top实现移动,如果是采用了其他定位方式需要根据实际情况做相应调整
  2. {passive:false}是为了让window的滑动事件能被阻止,如欲修改请注意调试是否符合实况
  3. 为节约资源,指令只永久监听一个start事件,其他的均在start后动态监听,由于EventListener可以重复添加,所以一轮结束后最好remove掉,此处必须用声明函数对象的方式进行增删,缘由在另一篇文章中介绍过:
    Vue项目根治IOS微信web中,输入项blur之后页面不回落的问题
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值