Vue - The PC side implements the dragging function of the div

To realize the drag function of div, you need to know the following native events and methods first;

1. Event:

method describe
onmousedown mouse button is pressed
onmousemove the mouse is moved
onmouseup mouse button is released

2. Method:

method describe
event.clientX Returns the horizontal coordinates of the mouse pointer relative to the browser page (or window) when the event was fired
event.clientY Same as above, returns vertical coordinates
event.offsetLeft Read-only property, returns the pixel value from the left border of the current element to the left of the positioned element (or the nearest element)
event.offsetTop Read-only property, returns the pixel value at the top of the current element's top border positioned element (or the nearest element)
event.clientHeight Read-only property, returns the pixel height of the element, the height includes padding, does not include border, margin and scrollbar, is an integer, and the unit is px
event.clientWidth Same as above, returns the pixel width of the element
event.offsetHeight Read-only property, it returns the pixel height of the element, the height includes padding and border, does not include margin, is an integer, and the unit is px
event.offsetWidth Same as above, returns the pixel width of the element

Note: clientHeight, clientWidth and offsetHeight offsetWidth get different sizes of element height and width, the offsetHeight offsetWidth I use here;

illustration:

insert image description here


The realized effect diagram is as follows:

Please add a picture description


3. The implementation is as follows :

important:

1. mousedown()It is necessary to calculate the position difference when the mouse is pressed, because the positions returned by the properties of clientX and offsetLeft are different and must be subtracted to obtain the actual click position of the mouse in the dragging element. This difference must be subtracted every time you drag Otherwise, the position you drag will always be the upper left corner of the element instead of the position you clicked before;

2. onmousemove ()The mouse move event and onmouseupthe mouse lift event should be added to the document element, because if the drag is too fast during the dragging process, the mouse moves out of the drag element, causing the drag element to lose the move event;

3. It is recommended to use the second method to judge the drag limit range. When I demonstrated the first method here, I found that there are often gaps when the div is moved to the side, which is not smooth;

4. onmouseupWhen the mouse is lifted, the mouse movement event needs to be unbound;

drag.view

<template>
  <div class="dragContainerEl">
    <div id="Drag" @mousedown="mousedown($event)" class="drag"></div>
  </div>
</template>

<script>
export default {
    
    
  name: "dragContainerEl",
  data() {
    
    
    return {
    
    
      DragEl: null,//拖动元素
      dragContainerEl: null,//容器元素
      // 位置差
      disX: 0,
      disY: 0,
      // 元素未拖动时的初始位置 绑定的是行内样式
      styleObj: {
    
    
        left: 0,
        top: 0
      }
    };
  },
  mounted() {
    
    
    this.DragEl = document.getElementById("Drag");
    this.dragContainerEl = document.getElementsByClassName("dragContainerEl")[0];
  },
  methods: {
    
    
    /* 鼠标按下 */
    mousedown(event) {
    
    
      // 1,计算位置差
      // 因为clientX和offsetLeft的属性返回的位置不一样 要相减得到鼠标在拖动元素内实际点击的位置
      // 后面每一次拖动时都要减去这个差值 否则就会造成你拖动的位置一直都是元素的左上角 而不是你之前点击的位置
      this.disX = event.clientX - this.DragEl.offsetLeft;
      this.disY = event.clientY - this.DragEl.offsetTop;

      //2, 获取拖动元素的高度和容器的高度 为了下面进行限制元素拖动的范围
      let dragHeight = this.DragEl.offsetHeight;
      let dragWidth = this.DragEl.offsetWidth;
      let dragContainerWidth = this.dragContainerEl.offsetWidth; //获取容器的高度和宽度
      let dragContainerHeight = this.dragContainerEl.offsetHeight;

      // 添加鼠标移动事件
      document.onmousemove = (el) => {
    
    
        // 3,获取鼠标移动位置
        let moveX = el.clientX - this.disX;
        let moveY = el.clientY - this.disY;

        // 4,限制拖动
        //控制范围:在元素 被拖拽的过程中 判断 元素的定位值 是否到达边界 如果到了 就不能在走了

        4.1第一种 限制范围的判断
        // if(moveX <=0 || moveY <=0){ // 控制上边界和左边界
        //   return
        // }
        // if(moveX >= dragContainerWidth - dragWidth || moveY >= dragContainerHeight - dragHeight){
    
    
        //   return
        // }

        4.2 第二种限制方位的判断 建议使用第二种; 第一种靠边时经常会有边距,不太丝滑
        // 左边界
        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.DragEl.style.left = moveX + "px";
        this.DragEl.style.top = moveY + "px";
      };
      /* 6,鼠标抬起解除事件 */
      document.onmouseup = () => {
    
    
        document.onmousemove = null;
      };
    }
  }
};
</script>
<style scoped lang="scss">
.dragContainerEl {
    
    
  position: relative;
  width: 100%;
  height: 100%;
  border: 1px solid red;
}
.drag {
    
    
  position: absolute;
  width: 50px;
  height: 50px;
  border: 5px solid yellowgreen;
  background-color: red;
  text-align: center;
}
</style>

Guess you like

Origin blog.csdn.net/qq_43886365/article/details/130411951