vue - pc端实现对div的拖动功能

news2024/10/6 12:22:56

实现对div的拖动功能,需要先要知道以下的一些原生事件和方法;

1,事件:

方法描述
onmousedown鼠标按钮被按下
onmousemove鼠标被移动
onmouseup鼠标按键被松开

2,方法:

方法描述
event.clientX返回当事件被触发时鼠标指针相对于浏览器页面(或窗口)的水平坐标
event.clientY同上,返回的是垂直坐标
event.offsetLeft只读属性,返回当前元素左边框距定位元素(或者最近的元素) 左侧的像素值
event.offsetTop只读属性,返回当前元素上边框距定位元素(或者最近的元素) 顶部的像素值
event.clientHeight只读属性,返回该元素的像素高度,高度包含内边距(padding),不包含边框(border),外边距(margin)和滚动条,是一个整数,单位是像素 px
event.clientWidth同上,返回该元素的像素宽度
event.offsetHeight只读属性,它返回该元素的像素高度,高度包含内边距(padding)和边框(border),不包含外边距(margin),是一个整数,单位是像素 px
event.offsetWidth同上,返回该元素的像素宽度

注意:clientHeight ,clientWidth 和 offsetHeight offsetWidth 获取元素高度宽度的尺寸不太一样,我这边使用的的 offsetHeight offsetWidth;

图例说明:

在这里插入图片描述


实现的效果图如下:

请添加图片描述


3,实现如下

重要说明:

1,mousedown() 鼠标按下时需要计算位置差,因为clientX和offsetLeft的属性返回的位置不一样 要相减得到鼠标在拖动元素内实际点击的位置, 后面每一次拖动时都要减去这个差值 否则就会造成你拖动的位置一直都是元素的左上角 而不是你之前点击的位置;

2,onmousemove ()鼠标移动事件和onmouseup 鼠标抬起事件要添加到 document 元素上面,因为在拖动的过程中如果拖动过快,鼠标移出了拖动元素,导致拖动元素丢失了移动事件;

3,拖动限制范围的判断建议使用第二种方法,第一种我这边演示的时候发现div靠边时经常会有间隙,不太流畅;

4,onmouseup鼠标抬起时需要解绑鼠标移动事件;

drag.vue

<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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/479450.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【BIM+GIS】Supermap加载实景三维倾斜摄影模型

OSGB是常见的倾斜模型格式,本文讲述如何在Supermap中加载实景三维倾斜摄影模型OSGB。 文章目录 一、生成配置文件二、加载倾斜模型1. 新建场景2. 添加模型3. 高程调整一、生成配置文件 点击【三维数据】→【数据管理】→【生成配置文件】。 参数设置如下: 源路径:选择倾斜模…

【12.HTML入门知识-flexbox布局】

flexbox布局 1 认识flexbox2 flex布局的重要概念3 flex布局的模型4 flex container/items相关的属性4.1 flex-direction:主轴的方向决定布局方向4.2 flex-wrap 单行或者多行排列4.3 flex-flow 简写4.4 justify-content 主轴对齐方式4.5 align-item 交叉轴单行对齐方式4.6 align…

【数据结构】JDK HashMap源码解析

目录 &#x1f31f;HashMap源码解析 &#x1f308;类的属性 &#x1f308;构造方法 &#x1f308;put方法 &#x1f31f;对比常用Map的子类实现: &#x1f31f;HashMap源码解析 JDK8之前&#xff0c;HashMap就是数组链表&#xff1b; JDK8之后&#xff0c;变成了数组链表红…

基于C++/CLI实现C#与C++互调过程中的注意事项

目录 一、基于C/CLI 的调用原理二、注意事项如何基于VS2010完成C#调用C开发过程1、生成C应用程序&#xff08;非托管代码&#xff09;2、基于C/CLI生成托管代码3、C#调用 如何基于VS2010完成C调用C#开发过程 三、C/CLI与COM组件对比 一、基于C/CLI 的调用原理 C/CLI &#xff…

数据结构---队列的实现

文章目录 前言一、什么是队列&#xff1f;二、队列接口的实现 1.队列结构的定义2.接口实现总结 前言 队列是一种特殊的线性表。 特殊之处在于它只允许在表的前端&#xff08;front&#xff09;进行删除操作&#xff0c;而在表的后端&#xff08;rear&#xff09;进行插入操作&a…

【Vue.js】1668- 初中级前端必须掌握的 10 个 Vue 优化技巧

优化 Vue.js 应用性能是每个前端开发人员都需要关注的问题。本文我将分享 10 个初中级前端必须掌握的 Vue.js 优化技巧&#xff0c;无论您是正在学习 Vue.js&#xff0c;还是已经在应用开发中使用它&#xff0c;希望这些技巧都会对你的工作有所帮助。 1. 优雅的设置 v-for 中的…

Java 中常见的 Exception 有哪些

Java 是一种广泛使用的编程语言&#xff0c;它的强大和流行程度在很大程度上归功于它的异常处理机制。异常是在程序执行期间出现的错误或意外情况。在 Java 中&#xff0c;异常是通过抛出和捕获异常对象来处理的。在本文中&#xff0c;我们将介绍 Java 中的一些常见异常类型及其…

浅堆深堆解读

浅堆&#xff08;Shallow Heap&#xff09; 浅堆是指一个对象所消耗的内存。在32位系统中&#xff0c;一个对象引用会占据4个字节&#xff0c;一个int类型会占据4个字节&#xff0c;long型变量会占据8个字节&#xff0c;每个对象头需要占用8个字节。根据堆快照格式不同&#x…

【STM32】知识补充 深入探讨预分频器

【STM32】知识补充 深入探讨预分频器 概述分频器是什么工作原理计数器预分频器触发器预分频器模数计数器预分频器上升沿和下降沿 应用场景微控制器时钟预分频通信系统中的频率合成计时器与 PWM 波形生成数字电路设计中的同步与计时 预分频器实现方法硬件预分频器软件预分频器 案…

Swift之深入解析如何使用和自定义高级运算符

一、前言 在我之前的博客 Swift之深入解析如何自定义操作符 介绍了“基本运算符”&#xff0c;Swift 还提供了数种可以对数值进行复杂运算的高级运算符&#xff0c;它们包含了在 C 和 Objective-C 中已经被大家所熟知的位运算符和移位运算符。与 C 语言中的算术运算符不同&…

【flask】理解flask的几个难点,难啃的骨头,线程隔离啥的

1.三种路由和各自的比较 2.配置文件所有的字母必须大写 3.if __name__的作用 4.核心对象循环引用的几种解决方式–难 5.Flask的经典错误 6.上下文管理器 7.flask的多线程和线程隔离 三种路由 方法1&#xff1a;装饰器 python C#, java 都可以用这种方式 from flask import F…

SSM整合(三) | 异常处理器 - 项目异常的处理方案

文章目录 异常处理器异常处理器快速入门项目异常处理 异常处理器 异常处理器快速入门 程序开发过程中不可避免的会遇到异常现象 出现异常现象的常见位置与常见原因如下&#xff1a; 框架内部抛出的异常&#xff1a;因使用不规范导致 数据层抛出的异常&#xff1a;因外部服务器…

使用Statsmodel进行假设检验和线性回归

如果你使用 Python 处理数据&#xff0c;你可能听说过 statsmodel 库。Statsmodels 是一个 Python 模块&#xff0c;它提供各种统计模型和函数来探索、分析和可视化数据。该库广泛用于学术研究、金融和数据科学。在本文中&#xff0c;我们将介绍 statsmodel 库的基础知识、如何…

【技巧】Excel序号设置自动更新

做Excel表格的时候&#xff0c;我们经常需要设置序号&#xff0c;在输入序号的时候&#xff0c;你是不是这样做&#xff1f;手动输入序号1&#xff0c;再向下填充&#xff0c;当遇到有不想要的内容&#xff0c;点删除后&#xff0c;发现中间的序号就不连贯了&#xff0c;再手动…

二十五、OSPF高级技术——开销值、虚链路、邻居建立、LSA、多进程

文章目录 调试指令&#xff08;三张表&#xff09;1、邻居表&#xff1a;dis ospf peer brief2、拓扑表&#xff08;链路状态数据库&#xff09;&#xff1a;dis ospf lsdb3、路由表&#xff1a;dis ip routing-table 一、OSPF 开销值/度量值&#xff08;cost&#xff09;1、co…

代码审计笔记之开篇

思想 代码审计是从软件测试发展而来&#xff0c;早起一般采用常规软件测试与渗透测试的手段来发现源码漏洞&#xff0c;但是随着软件规模的越来越大&#xff0c;架构越来越复杂&#xff0c;安全漏洞和后门也越来越多越来越隐蔽&#xff0c;这使得传统的软件测试方法很难检出源…

【Java入门合集】第二章Java语言基础(一)

【Java入门合集】第二章Java语言基础&#xff08;一&#xff09; 博主&#xff1a;命运之光 专栏JAVA入门 学习目标 掌握变量、常量、表达式的概念&#xff0c;数据类型及变量的定义方法&#xff1b; 掌握常用运算符的使用&#xff1b; 掌握程序的顺序结构、选择结构和循环结构…

C/C++每日一练(20230501)

目录 1. 对链表进行插入排序 &#x1f31f;&#x1f31f; 2. 找出小于平均值的数 ※ 3. 二叉树的最大深度 &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 对链表进行…

【五一创作】Apollo(入门)

Apollo(入门) Quick Start 配置中心是一种统一管理各种应用配置的基础服务组件 Apollo&#xff08;阿波罗&#xff09;是携程框架部门研发的分布式配置中心&#xff0c;能够集中化管理应用不同环境、不同集群的配置&#xff0c;配置修改后能够实时推送到应用端&#xff0c;并且…

Springboot 实战一个依赖解决XSS攻击

1. 什么是XSS介绍 XSS: Cross Site Scripting&#xff0c;为不和层叠样式表(Cascading Style Sheets, CSS) 的缩写混淆&#xff0c;故将跨站脚本攻击缩写为XSS。 恶意攻击者往Web页面里插入恶意Script代码&#xff0c;当用户浏览该页之时&#xff0c;嵌入其中 Web里面的Scrip…