Vue custom v-drag command to achieve mouse drag

Vue custom v-drag command to achieve mouse drag

1. Effect

Use the custom drag instruction v-drag to achieve the effect of mouse dragging.
insert image description here

2. Related concepts

  • Element.clientWidth: The visible width of the element (excluding scroll bars).
  • Element.clientHeight: The visible height of the element (excluding scroll bars).
  • MouseEvent.clientX: the horizontal coordinates of the mouse relative to the upper left corner of the browser (excluding scroll bars), and the corresponding MouseEvent.pageX: the horizontal coordinates relative to the entire document (that is, including scrolling).
  • MouseEvent.clientY: the vertical coordinates of the mouse relative to the upper left corner of the browser (excluding the scroll bar), and the corresponding MouseEvent.pageY: the vertical coordinates relative to the entire document (that is, including scrolling).
  • HTMLElement.offsetLeft: The offset distance of the upper left corner of the current element relative to the left side of the parent node (HTMLElement.offsetParent).
  • HTMLElement.offsetTop: The offset distance of the upper left corner of the current element relative to the top of the parent node (HTMLElement.offsetParent).
    insert image description here

3. Implementation ideas

Customize the drag command v-drag, the implementation idea is as follows:

  • Set position: fixed or position: absolute for the element to be dragged, so that the position of the current element is relative to the position of the upper left vertex of the browser.

Pay attention to distinguishing several attribute values ​​​​of Position:

  • Absolute: Absolute positioning is positioned relative to the nearest parent element that is not statically positioned.
  • Fixed: Absolute positioning, which is positioned relative to the browser window, is fixed and will not scroll with the screen.
  • Relative: relative positioning, which is positioned relative to its original position.
  • Relative: relative positioning, which is positioned relative to its original position.

The position of the element is obtained by adjusting the coordinates of the upper left vertex, so we need to know the coordinates of the upper left vertex after the element is dragged, so as to move the element to the specified position.

The first step is to calculate the position of the mouse on the element before moving it:

let disX = e.clientX - el.offsetLeft;
let disY = e.clientY - el.offsetTop;

Knowing the relative position of the mouse, the subsequent mouse movement, as long as the mouse coordinates after the movement are known, the coordinates of the upper left vertex of the element at the current position can be easily calculated.

Calculate the coordinates of the upper left vertex after the element is moved:

el.style.left = e.clientX - disX + "px"; //设置定位元素的左部位置
el.style.top = e.clientY - disY + "px"; //设置定位元素的顶部位置

Overall process : Get the position of the mouse on the element when the mouse is pressed, calculate and set the coordinate position of the upper left vertex of the element every time it moves, and disable the down listening event when the mouse is released, otherwise it will continue to execute.

4. Code

Use directives in the component to register a custom drag instruction v-drag, and use "v-drag" on the element you want to drag.

  • Implementation code
<template>
  <div class="box" v-drag></div>
</template>

<script>
export default {
    
    
  //注册局部自定义指令
  directives: {
    
    
    //el:指令所绑定的元素
    drag(el, bindings) {
    
    
      //鼠标按下事件
      el.onmousedown = function(e) {
    
    
      	// 获取鼠标在元素上的位置
        let disX = e.clientX - el.offsetLeft;
        let disY = e.clientY - el.offsetTop;
        //鼠标移动事件
        document.onmousemove = function(e) {
    
    
          el.style.left = e.clientX - disX + "px"; //设置定位元素的左部位置
          el.style.top = e.clientY - disY + "px"; //设置定位元素的顶部位置
        };
        //鼠标松开事件
        document.onmouseup = function() {
    
    
          //要禁用掉down的监听事件,否则会一直执行
          document.onmousemove = document.onmouseup = null;
        };
      };
    },
  },
};
</script>

<style scoped>
.box {
    
    
  width: 300px;
  height: 300px;
  background-color: cyan;
  position: fixed;
  left: 100px;
  top: 100px;
}
</style>

Guess you like

Origin blog.csdn.net/weixin_43288600/article/details/121431120
Recommended