vue – 移动端实现对div的拖动功能

  • Post author:
  • Post category:vue


移动端实现对div的拖动功能,需要先要知道以下移动端的一些原生事件和方法;本质上和pc端的操作是一样的;

pc端实现对div的拖动功能 :

链接


事件

方法 描述
touchstart 触摸元素时触发
touchmove 元素滑动时触发
touchend 触摸元素抬起时触发


方法

方法 描述
event.targetTouches[0].pageX 当前手指的X轴坐标,相对于浏览器页面或窗口
event.targetTouches[0].pageY 当前手指的Y轴坐标,相对于浏览器页面或窗口
event.offsetLeft 只读属性,返回当前元素左边框距定位元素(或者最近的元素) 左侧的像素值
event.offsetTop 只读属性,返回当前元素上边框距定位元素(或者最近的元素) 顶部的像素值
event.offsetHeight 只读属性,它返回该元素的像素高度,高度包含内边距(padding)和边框(border),不包含外边距(margin),是一个整数,单位是像素 px
event.offsetWidth 同上,返回该元素的像素宽度

注意:手指移动也会触发滚动屏幕(如果宽度溢出出现滚动条的话),所以要阻止默认的屏幕滚动 event.

preventDefault

();


拖动原理

主要是改变定位元素的定位值来实现位置的移动;定位值 = 手指滑动中的位置 – 手指刚触摸时候的初始位置 和距离限制;

实现代码:

<template>
  <!-- 移动端拖拽实现 -->
  <div class="dropContainer">
    <div id="Drop" :style="style" @touchmove="touchmove($event)" @touchstart="touchstart($event)" class="drop"></div>
  </div>
</template>

<script>
export default {
  name: "dropContainer",
  data() {
    return {
      DropEl: null,
      dropContainer: null,
      // 元素未拖动时的初始位置 绑定的是行内样式
      style: {
        top: "100px",
        left: "100px"
      },
      // 位置差
      disX: 0,
      disY: 0
    };
  },
  computed: {},
  mounted() {
    // 获取元素
    this.DropEl = document.getElementById("Drop");
    this.dropContainer = document.getElementsByClassName("dropContainer")[0];
  },
  methods: {
    // 手指落下时触发
    touchstart(event) {
      // 1,计算位置差 因为clientX和offsetLeft的属性返回的位置不一样 要相减得到拖动元素内实际点击的位置
      // pageX 永远大于等于 offsetLeft pageY也是同理
      this.disX = event.targetTouches[0].pageX - this.DropEl.offsetLeft;
      this.disY = event.targetTouches[0].pageY - this.DropEl.offsetTop;
    },

    // 手指移动时触发
    touchmove(event) {
      // 2,获取手指移动的实时位置  需要减去位置差
      let moveX = event.targetTouches[0].pageX - this.disX;
      let moveY = event.targetTouches[0].pageY - this.disY;

      // 3,获取容器的宽高和拖动元素的宽高  每一次移动都会获取一次 ,建议放在外面进行获取
      let dragHeight = this.DropEl.offsetHeight;
      let dragWidth = this.DropEl.offsetWidth;
      let dragContainerWidth = this.dropContainer.offsetWidth; //获取容器的高度和宽度
      let dragContainerHeight = this.dropContainer.offsetHeight;

      // 4,控制范围:在元素 被拖拽的过程中 判断 元素的定位值 是否到达边界 如果到了 就不能在走了
      if (moveX <= 0) {
        moveX = 0;
      }
      // 上边界
      if (moveY <= 0) {
        moveY = 0;
      }
      //下边界  容器高度 - 拖动元素高度
      if (moveY >= dragContainerHeight - dragHeight) {
        moveY = dragContainerHeight - dragHeight;
      }
      //右边界   容器宽度 - 拖动元素宽度
      if (moveX >= dragContainerWidth - dragWidth) {
        moveX = dragContainerWidth - dragWidth;
      }
      // 5,开始移动
      this.style.left = moveX + "px";
      this.style.top = moveY + "px";
    }
  }
};
</script>

<style lang="scss" scoped>
.dropContainer {
  width: 100%;
  height: 100vh;
}
.drop {
  position: fixed;
  width: 30px;
  height: 30px;
  border: 5px solid red;
  border-radius: 50%;
  background-color: red;
  text-align: center;
}
</style>



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