Vuejs自定义指令实现移动端和pc端的div随意拖拽。

Posted 一直在路上的小仙女

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vuejs自定义指令实现移动端和pc端的div随意拖拽。相关的知识,希望对你有一定的参考价值。

在Vue里提倡操作虚拟dom尽量不操作真实是dom。但在频繁操作dom的情况下显然体验不好,使用Js操作真实dom来实现div的随意拖拽。
这里为了复用,写成了指令,方便其他页面使用,直接调指令,不需要重复写。

pc端:

<template>
  <div class="ha">
    <div class="box"  v-wahaha></div>
  </div>
</template>
<script>
export default {
  data(){
    return{x:"",y:"",}
  },
  mounted(){
    let box = document.querySelector('.box')
    let move = JSON.parse(window.localStorage.getItem("move"))
    box.style.left = move.x
    box.style.top = move.y
  },
  directives:{
    wahaha(el,binding){
      el.onmousedown = function(ev){
        var x = ev.clientX - el.offsetLeft;
        var y = ev.clientY - el.offsetTop;
        el.onmousemove = function(ev){
          window.localStorage.removeItem("move")
          this.x = ev.clientX - x + 'px';
          this.y = ev.clientY - y + "px" ;
          el.style.left = this.x
          el.style.top = this.y
          window.localStorage.setItem("move",JSON.stringify({x:this.x,y:this.y}))
        }
      // window.localStorage.setItem("move",this.x)  拿不到
       el.onmouseup = function(ev){
       el.onmousemove = el.onmouseup = null;
       }
       return false;
      }
    }
  }
}
</script>
<style scoped>
.box{
  width: 200px;
  height: 200px;
  position: absolute;
  top: 100px;
  left: 100px;
  background: red;
}
</style>

用到的div直接加上 V-wahaha指令即可。
pc端可能存在浏览器兼容,可根据自己的需要优化。
图解:

移动端:

代码复制直接用。

<template>
  <div >
    <div id="box" v-wahaha></div>
  </div>
</template>
  <script type="text/javascript">
  export default {
    mounted(){
      this.$nextTick(()=>{
        var box = document.getElementById('box')
        var move = JSON.parse(window.localStorage.getItem("move"));
        box.style.left = `${move.x}px`;
        box.style.top = `${move.y}px`;
      })
    },
    directives:{
      drag(el,binding){
        var lenX //定义x轴相对手指点击位置距离盒子元素左边框距离
        var lenY //定义y轴相对手指点击位置距离盒子元素上边框距离
        var maxW //定义盒子在x轴上可移动的最大值
        var maxH //定义盒子在y轴上可移动的最大值
        el.addEventListener('touchstart',function(e){//按下去时
          maxW = e.srcElement.offsetParent.clientWidth-el.offsetWidth;
          maxH = e.srcElement.offsetParent.clientHeight-el.offsetHeight;
          //  maxW = document.body.clientWidth/clientHeight - el.offsetWidth;
          var ev = e || window.event;
          var touch = ev.targetTouches[0];
          lenX = touch.clientX - el.offsetLeft;
          lenY = touch.clientY - el.offsetTop;
           el.addEventListener("touchmove",defaultEvent,false);//注释后 靠边弹性返回
           window.localStorage.removeItem("move")
       })
        el.addEventListener('touchmove',function(e){//拖动时
        var ev = e || window.event;
        var touch = ev.targetTouches[0];
        var left = touch.clientX - lenX;
        var top = touch.clientY - lenY;
        if(left<0){
           left=0;
        }else if (left>=maxW) {
            left=maxW;
        }
        if(top <0){
            top =0;
        }else if (top >=maxH) {
            top =maxH;
        }
        el.style.left = left + 'px';
        el.style.top = top + 'px';
        window.localStorage.setItem("move",JSON.stringify({x:left,y:top}))
      })
        el.addEventListener('touchend',function(){ //松开时
        document.removeEventListener("touchmove",defaultEvent);
        })
        function defaultEvent(e) {
          e.preventDefault();
        }
      }
    },
  }
</script>
<style media="screen">
  #box {
    width: 100px;
    height: 100px;
    left: 10px;
    top: 10px;
    background:pink;
    position: absolute;
  }
</style>

图解:

以上封的是局部指令,只可在当前页面使用指令。
以下是全局指令,可在所有页面使用指令。

Vue.directive("wahaha",
  (el,binding)=>{
    var lenX //定义x轴相对手指点击位置距离盒子元素左边框距离
    var lenY //定义y轴相对手指点击位置距离盒子元素上边框距离
    var maxW //定义盒子在x轴上可移动的最大值
    var maxH //定义盒子在y轴上可移动的最大值
    el.addEventListener('touchstart',function(e){//按下去时
      maxW = e.srcElement.offsetParent.clientWidth-el.offsetWidth;
      maxH = e.srcElement.offsetParent.clientHeight-el.offsetHeight;
      //  maxW = document.body.clientWidth/clientHeight - el.offsetWidth;
      var ev = e || window.event;
      var touch = ev.targetTouches[0];
      lenX = touch.clientX - el.offsetLeft;
      lenY = touch.clientY - el.offsetTop;
       el.addEventListener("touchmove",defaultEvent,false);//注释后 靠边弹性返回
       window.localStorage.removeItem("move")
    })
    el.addEventListener('touchmove',function(e){//拖动时
    var ev = e || window.event;
    var touch = ev.targetTouches[0];
    var left = touch.clientX - lenX;
    var top = touch.clientY - lenY;
    if(left<0){
       left=0;
    }else if (left>=maxW) {
        left=maxW;
    }
    if(top <0){
        top =0;
    }else if (top >=maxH) {
        top =maxH;
    }
    el.style.left = left + 'px';
    el.style.top = top + 'px';
    window.localStorage.setItem("move",JSON.stringify({x:left,y:top}))
    })
    el.addEventListener('touchend',function(){ //松开时
    document.removeEventListener("touchmove",defaultEvent);
    })
    function defaultEvent(e) {
      e.preventDefault();
    }
  }
)

有好的优化的欢迎指出,有帮助到就给个支持吧。。。。。

以上是关于Vuejs自定义指令实现移动端和pc端的div随意拖拽。的主要内容,如果未能解决你的问题,请参考以下文章

前端开发中pc端和移动端的区别

使用vue实现简单键盘,支持移动端和pc端

swiper 移动端和PC端的常用解决方案

前端:移动端和PC端的区别

移动端和PC端的区别有哪些?

vuecli3 实现 移动端和pc端 界面切换(两套代码)