前端功能拖拽篇:dragleave拖拽事件穿透子元素的优雅解决方案

文章目录

  • 前情提要
  • 应用场景
    • ⭐拖拽改变元素位置
    • ⭐拖拽改变目标区域的样式
    • ⭐dragleave拖拽事件穿透子元素的优雅解决方案
  • 最后

前情提要

在这里插入图片描述
在前端工作过程中,避免不了要接触各种技术,拖拽就是其中一个,大部分关于拖拽的基础知识和Demo都在MDN中写的很详细的,这里便不再赘述,给大家分享一个MDN飞机票


应用场景

每个人会接触不同的场景和需求,但是底层都是基于这些事件及API的,那我就直接分享几个有价值的点,可以节省大家的时间。

⭐拖拽改变元素位置

这个功能要依据几个事件
1、dragstart
2、dragover //dragover必须要在此事件中取消浏览器的默认行为,否则drop事件不会生效
3、drop

// 第一步,记录鼠标指针在元素上的偏移量
const rightItemDragStart = (event: any) => {
  // 记录初始鼠标偏移量
  mouseOffsetMap.value = { x: event.offsetX, y: event.offsetY }
  // 传递拖拽元素id
  event.dataTransfer.setData('text/plain', event.target.id)
  event.dataTransfer.setData('rightDrag', true)
}
// 第二步 设置阻止默认行为
const handleDragOver = (event: DragEvent) => {
  // 阻止默认行为以允许放置
  event.preventDefault()
}
// 第三步 计算元素位置赋值
const handleDrop = (event: any) => {
	// eventPos 这个位置就是元素放置后的准确位置
    eventPos = {
      x: event.offsetX - mouseOffsetMap.value.x,
      y: event.offsetY - mouseOffsetMap.value.y,
    }
    ...
    
  // 阻止默认行为(会作为某些元素的链接打开)
  event.preventDefault()
}

⭐拖拽改变目标区域的样式

依据俩个事件,要绑定给目标Dom
1、dragenter
2、dragleave

/**
 * 处理拖拽进入事件
 *
 * @param event 拖拽事件对象
 */
const handleDragEnter = (event: any) => {
  rightWrapRef.value?.classList.add('out-line')
}
/**
 * 当拖拽元素离开目标区域时触发
 *
 * @param event 拖拽事件对象
 */
const handleDragLeave = (event: DragEvent) => {
  rightWrapRef.value?.classList.remove('out-line')
}

⭐dragleave拖拽事件穿透子元素的优雅解决方案

如果目标区域的dom结构比较复杂,比如我在工作中的场景这样:
在这里插入图片描述
我想从右测往左侧的列表里拖拽,并且在进入左侧区域的时候,为区域增加一个虚线框,鼠标离开的时候取消虚线框。但此时问题出现了,在我拖拽进入区域后,每一个子元素的区域都会致使我重复触发enter,leave,导致虚线框闪烁,在一番调研后发现确实有这个问题,它不是事件的冒泡,也不是默认行为,而是改方法的特性导致的,所以大家只好另辟蹊径,怎么做的都有,但我认为最优雅的是下面这种。主要利用俩个方法
1、handleLeftDragEnter
2、handleLeftDragLeave

const draggingCounter = ref(0)
const handleLeftDragEnter = (event: any) => {
   draggingCounter.value++
  // 左侧元素放入左侧区域不处理
  leftWrapRef.value?.classList.add('out-line')
}
const handleLeftDragLeave = (event: any) => {
  draggingCounter.value--
  if(draggingCounter.value === 0) {
     leftWrapRef.value?.classList.remove('out-line')
  }
}

这里利用一个计数变量,大家看我打印这个一次拖拽的逻辑就很好理解了
在这里插入图片描述
俩次进入元素是因为进入最外部区域算一次,途径子元素算一次,离开子元素也是同理,我们通过判断数值为0来推导离开父元素的区域也是很合理的做法。大家如果还有什么好的建议和观点欢迎讨论学习。

最后

📚 vue专栏
☃️ 个人简介:一个喜爱技术的人。
🌞 励志格言: 脚踏实地,虚心学习。
❗如果文章还可以,记得用你可爱的小手点赞👍关注✅,我会在第一时间回、回访,欢迎进一步交流。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【智能算法】吸引-排斥优化算法(AROA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年,K Cymerys受到自然界中吸引-排斥现象启发,提出了吸引-排斥优化算法(Attraction–Repulsion Optimization Algorithm, AROA)。 2.算法…

Verilog HDL基础知识(二)

引言:本文继续介绍Verilog HDL基础知识,重点介绍赋值语句、阻塞与非阻塞、循环语句、同步与异步、函数与任务语法知识。 1. 赋值语句 在Verilog中,有两种进行赋值的方法,即连续赋值语句和过程赋值语句(块&#xff09…

[vue2项目]vue2+supermap[mapboxgl]+天地图之地图的初始化

Supermap参考教程 天地图 一、安装 1、终端:npm install @supermap/vue-iclient-mapboxgl 2、在package.json文件的dependencies查看@supermap/vue-iclient-mapboxgl依赖是否安装成功。 3、在mian.js全局引入 import VueiClient from @supermap/vue-iclient-mapboxgl; Vue.u…

新一代目标检测来了:YOLOv10 | 理论概要

点击下方卡片,关注“小白玩转Python”公众号 YOLO的简史 在我们深入探讨YOLOv10之前,让我们回顾一下YOLO的发展历程。YOLO在实时目标检测领域一直是先驱,兼顾速度和准确性。从YOLOv1到YOLOv9,每个版本在架构、优化和数据增强方面都…

Ansible04-Ansible Vars变量详解

目录 写在前面6 Ansible Vars 变量6.1 playbook中的变量6.1.1 playbook中定义变量的格式6.1.2 举例6.1.3 小tip 6.2 共有变量6.2.1 变量文件6.2.1.1 变量文件编写6.2.1.2 playbook编写6.2.1.3 运行测试 6.2.2 根据主机组使用变量6.2.2.1 groups_vars编写6.2.2.2 playbook编写6.…

场外个股期权零门槛开户安全吗?

一般来说场外个股期权是需要5000w门槛验资20个交易日的,但门槛对于大多数散户而言是很难达到的,因此场外个股期权零门槛开户因此产生,个人散户参与场外个股期权可以通到机构通道方直接下单交易,下文为大家揭秘场外个股期权零门槛开…

基于SpringBoot的旅游攻略信息系统的设计与实现

文档介绍 用户群体 针对已经学习过SpringBoot的同学,希望通过一个项目来加强对框架的应用能力,增加项目经验 针对需要完成大学期间的毕设项目的同学,可以通过此文档了解整个系统技术架构,为自己的毕设论文提供指导性建议 文档内容 此文档内容可以让学习此实战项目的同学有一…

2024年5月月终总结

一转眼4月份又过去了,按照年初的承诺,每月照例要写一个月总结,简单回顾下: 1) 英语学习继续进行: 百词斩: 不背单词: 每日英语听力: 2)中医学习每天15分钟,没有中断。 …

数据库系统概论(超详解!!!)第十节 过程化SQL

1.Transact-SQL概述 SQL(Structure Query Language的简称,即结构化查询语言) 是被国际标准化组织(ISO)采纳的标准数据库语言,目前所有关系数据库管理系统都以SQL作为核心,在JAVA、VC、VB、Delphi等程序设计语言中也可使用SQL,它是…

AIGC全面揭秘:人工智能内容生成的无限可能!

一、引言 随着人工智能技术的不断发展,AIGC(人工智能生成内容)技术逐渐受到广泛关注。本文将全面介绍AIGC的相关知识。 二、AIGC简介 AIGC是利用人工智能技术自动生成内容的一种技术。它可以根据给定的输入数据和规则,自动产生符…

详解 Spark 编程之 RDD 依赖关系

一、依赖与血缘关系 依赖:两个相邻 RDD 之间的关系血缘关系:多个连续的 RDD 的依赖由于 RDD 不会保存数据,为了提高容错性,每个 RDD 都会保存自己的血缘关系,一旦某个转换过程出现错误,可以根据血缘关系重新…

开源VS闭源:AI未来的十字路口

人工智能领域的发展日益加速,其中关于模型的开源和闭源策略引起了业界的广泛关注。开源策略指的是将软件的源代码公开,允许任何人自由使用、研究甚至改进;而闭源策略则是指软件的源代码不公开,只有特定的个体或组织有权访问和修改…

【IPFS应用开发】基于IPFS的视频播放器

本系列文章是针对 https://blog.csdn.net/weixin_43668031/article/details/83962959 内容的实现所编写的。开发经历包括思考过程、重构和推翻重来。 基于IPFS的视频播放器 想写一个真正的、基于IPFS的,可以播放IPFS上的视频的程序支持多种数据加载格式同时支持单文…

docker部署Minio对象存储及使用

1.拉取镜像 docker pull minio/minio2.创建数据目录 mkdir -p /data/minio/data3.启动容器 docker run -p 39000:9000 -p 39090:9090 \ --name minio \ -d --restartalways \ -e "MINIO_ACCESS_KEYjyadmin" \ -e "MINIO_SECRET_KEYjyzx2023" \ -v /data…

C++数据结构之:链List

摘要: it人员无论是使用哪种高级语言开发东东,想要更高效有层次的开发程序的话都躲不开三件套:数据结构,算法和设计模式。数据结构是相互之间存在一种或多种特定关系的数据元素的集合,即带“结构”的数据元素的集合&am…

用esp prog烧录ESP32-C3板踩坑

附ESP32C3的GPIO一览: vscode选择Jtag烧录,终端输出esp_usb_jtag: could not find or open device: D:\Devtools\Espressif\tools\openocd-esp32\v0.12.0-esp32-20230921\openocd-esp32\bin\openocd.exe -f board/esp32s3-builtin.cfgOpen O…

xxl-job的使用

介绍 在分布式中,很多微服务可能存在多实例部署的现象,如果在某个具体的微服务中实现一个定时任务,而该微服务存在多个实例的话,那么会导致该定时任务在不同实例中都会进行执行!这很容易导致脏数据、数据重复等问题&am…

黑白群晖激活AME(Advanced Media Extention)

黑群晖激活Advanced Media Extensions(AME)解码HEVC视频和HEIC图片 声明:此教程在正版群晖系统中进行的操作,虽然也能用于非正版系统中AME的安装,但是在非正版系统中安装AME属于破解行为,对系统造成的影响和…

安装vllm的时候卡主:Collecting vllm-nccl-cu12<2.19,>=2.18 (from vllm)

按照vllm的时候卡主: ... Requirement already satisfied: typing-extensions in /home/wangguisen/miniconda3/lib/python3.10/site-packages (from vllm) (4.9.0) Requirement already satisfied: filelock>3.10.4 in /home/wangguisen/miniconda3/lib/python…

落地台灯有什么作用?五款口碑好的落地台灯推荐

落地台灯有什么作用?面对长时间工作、学习已成为当代年轻人的真实写照,据目前不完全统计,60%以上的人群每天用眼时间都已经超过10小时,高强度的的用眼以及不可确定的环境因素都易导致双眼出现干涉、酸痛、红血丝等情况&#xff0c…