vue适配双端浮标(悬浮球)拖拽

适配双端浮标拖拽

最近写到一个需求是悬浮球拖动,看了很多网上的案例,要么移动端很流畅那么PC端就很卡,要么双端(ps:双端是指移动端和PC端)都很卡。于是自己就在网上百度改造了一款双端基本上很流畅的就能拖拽

首先先写一个div壳子(拖拽就是改变这个div的位置)

<div 
	class="box-new" 
	v-show="boxnew" 
	v-drag 
	@click="onBtnClicked" 
	ref="floatButton"
    :style="{'width': itemWidth + 'px', 'height': itemHeight + 'px', 'left': left + 'px', 'top':    	top + 'px'}"
    >
  	<img src="img/xuanfuqiu.png"  draggable="false" />
</div>

这里面的 v-drag 主要是用于移动端

之后就要去注册一下事件(因为我是在html中引入的vue.js所以我的data中没有写return 如果大家是在vue项目的话记得请在return中写哦~~)

data: {
  boxnew: true,
  bindicon: true,
  //浮标拖动
  clientWidth: 0,
  clientHeight: 0,
  timer: null,
  currentTop: 0,
  left: 90,
  top: 0,
  activeArr: "GiftBags",
},
directives: {
  drag: { // 在要拖拽的元素上加 v-drag
    // 指令的定义
    bind: function (el) {
      let odiv = el //获取当前元素
      odiv.onmousedown = function (e) {
        //算出鼠标相对元素的位置
        let startX = e.clientX;
        let startY = e.clientY;
        let starL = odiv.offsetLeft
        let starT = odiv.offsetTop

        let maxLeft = document.documentElement.offsetWidth - odiv.offsetWidth;
        starL = starL > maxLeft ? maxLeft : starL;

        document.onmousemove = function (e) {
          odiv.style.transition = 'none';
          // 元素的位置
          let left = e.clientX - startX + starL;
          let top = e.clientY - startY + starT;

          // 边界判断
          let maxLeft = document.documentElement.offsetWidth;
          let minLeft = 0;
          left = left > maxLeft ? maxLeft : left;
          left = left < minLeft ? minLeft : left;
          //绑定元素位置到positionX和positionY上面
          this.positionX = top
          this.positionY = left
          //移动当前元素
          odiv.style.left = left + 'px'
          odiv.style.top = top + 'px'
        }
        document.onmouseup = () => {
          let boxLeft = parseInt(odiv.style.left),
            pageX = document.documentElement.offsetWidth - odiv.offsetWidth;

          document.onmousemove = null
          document.onmouseup = null

          // 悬浮左右滑动的逻辑
          if (boxLeft < pageX / 2) {
            odiv.style.left = 0 + 'px';
            odiv.style.transition = 'left .3s';
          } else {
            odiv.style.left = pageX + 'px';
            odiv.style.transition = 'left .3s';
          }
        }
      }
    },
  },
},
props: {
  itemWidth: {
    // 悬浮按钮宽度
    type: Number,
    default: 50
  },
  itemHeight: {
    // 悬浮按钮高度
    type: Number,
    default: 50
  },
  gapWidth: {
    // 距离左右两边距离
    type: Number,
    default: -25
  },
  coefficientHeight: {
    // 从上到下距离比例
    type: Number,
    default: 0.1
  }
},

后面我们就需要去做一些拖拽的操作啦,这些操作可都得写在methods下面哦

  onBtnClicked() {
    this.$emit("onFloatBtnClicked");
  },
  handleScrollStart() {
        this.timer && clearTimeout(this.timer);
        this.timer = setTimeout(() => {
          this.handleScrollEnd();
        }, 300);
        this.currentTop =
          document.documentElement.scrollTop || document.body.scrollTop;
        if (this.left > this.clientWidth / 2) {
          this.left = this.clientWidth - this.itemWidth / 2;
        } else {
          this.left = -this.itemWidth / 2;
        }
     },
     handleScrollEnd() {
        let scrollTop =
          document.documentElement.scrollTop || document.body.scrollTop;
        if (scrollTop === this.currentTop) {
          if (this.left > this.clientWidth / 2) {
            this.left = this.clientWidth - this.itemWidth - this.gapWidth;
          } else {
            this.left = this.gapWidth;
          }
        }
      },

	

最后我在mounted里面做了一个判断是pc然后再确定悬浮球的边距

 mounted() {
      // 判断Pc端
      if (document.documentElement.clientWidth > 750) {
        this.$refs.floatButton.vue = this; // 将实例传递给当前元素
      }
      //移动端拖拽
      this.clientWidth = document.documentElement.clientWidth;
      this.clientHeight = document.documentElement.clientHeight;
      this.left = this.clientWidth - this.itemWidth - this.gapWidth;
      this.top = this.clientHeight * this.coefficientHeight;
      this.$nextTick(() => {
        const floatButton = this.$refs.floatButton;
        floatButton.addEventListener("touchstart", () => {
          floatButton.style.transition = "none";
        });

        // 在拖拽的过程中,组件应该跟随手指的移动而移动。
        floatButton.addEventListener("touchmove", e => {
          console.log("移动中", e);
          if (e.targetTouches.length === 1) {
            // 一根手指
            let touch = e.targetTouches[0];
            this.left = touch.clientX - 40;
            this.top = touch.clientY - 25;
          }
        });

        // 拖拽结束以后,重新调整组件的位置并重新设置过度动画。
        floatButton.addEventListener("touchend", () => {
          floatButton.style.transition = "all 0.3s";
          if (this.left > document.documentElement.clientWidth / 2) {
            this.left = document.documentElement.clientWidth - 20;
          } else {
            this.left = -20;
          }
        });
      });
    },

到这,,,,悬浮球拖拽的操作就完成了,如果大家有需要的话完全拿代码去试一试哦,最后谢谢大家的采纳,如果有什么更好的方法欢迎联系,谢谢大家~~


版权声明:本文为weixin_48119454原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。