当前位置:首页 » 《随便一记》 » 正文

Vuejs自定义指令实现移动端和pc端的div随意拖拽。_一直在路上的小仙女的博客

110 人参与  2021年12月02日 11:43  分类 : 《随便一记》  评论

点击全文阅读


在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();
    }
  }
)

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


点击全文阅读


本文链接:http://zhangshiyu.com/post/31515.html

盒子  指令  定义  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 天下所有女子都爱慕英雄,更爱慕那些从天而降救了自己的英雄。《明月揽君怀》
  • 《黑雪花》司诀宋淮月完结免费阅读(司诀宋淮月)全文阅读
  • 《完美重生》宋承与沈清怡热门小说_宋承与沈清怡全文阅读
  • 半路温柔崔致颜茴全本小说_(半路温柔)全文阅读
  • ARM架构的大发展不仅是芯片行业以及智能计算行业的一个机遇,也是当前我们所推动的国产替代浪潮的一个战略机遇。
  • 《指导意见》提出,着力打造人工智能重大场景。提升人工智能场景创新能力。
  • 拍照:一加IMX766有绿厂多年的优化,拍照更强;红米用的是HM6传感器,虽是一亿像素,但底小。
  • 8月11日晚上,小米集团创始人、董事长雷军进行了2022年度演讲,并发布了小米旗下一系列新产品和新技术。
  • 最新一代 DLZ-HV-200 型高效等离子体点火及稳燃系统近日在国家能源集团江西神华九江发电公司 2 号机组成功运行
  • 《指导意见》提出,着力打造人工智能重大场景。提升人工智能场景创新能力。加快推动人工智能场景开放
  • 8月11日,在雷军2022年度演讲中,小米发布全尺寸人形仿生机器人“CyberOne”,内部昵称“铁大”。
  • 《意见》指出,场景创新是以新技术的创造性应用为导向,以供需联动为路径,实现新技术迭代升级和产业快速增长的过程。
  • 赞助商广告

    关于我们 | 我要投稿 | 网站收录 | 免费二级域名 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备12007198号-1