首页 > 其他分享 >一文搞懂drag&drop浏览器拖放功能的实现

一文搞懂drag&drop浏览器拖放功能的实现

时间:2024-04-27 20:24:00浏览次数:24  
标签:放置 drop 事件 设置 搞懂 拖拽 拖放 dataTransfer

       拖放功能,即将一个元素从一个区域,通过拖拽,放置到另一个区域。常见的应用是将文件或图片从一个区域,拖放到另一个区域。中文常常把这表述成拖拽,实际上拖拽的描述并不准确,应该叫拖放,因为drag事件和drop事件是成对使用的,即拖拽和放置。

       drag在拖拽动作发生时触发,携带被拖拽元素的信息,drop在放置元素时触发,接收传递的拖拽元素的信息。

       由于常常表述成拖拽,所以有些人在实现拖动功能时以为会触发drag事件,比如侧边栏拖拽。实际上drag是为拖放功能设计的(要配合drop),拖动(or拖拽)的功能应该用mousemove事件去实现,用错事件就会觉得怎么拖拽功能好难啊。

P.S.

drag和mousemove事件都是在移动鼠标的过程中触发,所以两个事件是会冲突的,如果发现其中一个事件不生效,可以检查下是不是因为有元素绑定了其中一个事件,导致另一个事件没有trigger。

具体实现

       拖放,拖拽和放置,那么自然需要一个拖拽的区域,和一个放置的区域。

       首先,要定义允许拖拽的元素。浏览器的默认行为是,文本、图像和链接是允许拖拽的。即<p>、<img>、<a>标签是默认允许拖拽的,其他元素要允许拖拽,则要设置draggle="true"。这个属性不允许简写。<div draggable ></div>并不会生效。

  其次,要定义拖拽的数据。比如,拖拽的是文本,则设置成文本格式,并设置拖拽的数据内容。拖拽的是图片,则设置成图片格式,设置数据内容。定义成图片格式,那么拖拽的时候,鼠标旁边就会显示一张设置的图片。设置的拖拽数据可以有多个。

      先给拖拽的元素绑定dragstart事件,再设置dataTransfer。示例代码如下:

function dragstart_handler(ev) {
  // 添加拖拽数据
  ev.dataTransfer.setData("text/plain", ev.target.innerText);
  ev.dataTransfer.setData("text/html", ev.target.outerHTML);
  ev.dataTransfer.setData(
    "text/uri-list",
    ev.target.ownerDocument.location.href,
  );
}

       拖放相关的事件对象event中,有一个dataTranster属性,这个属性保存着拖放过程中的数据。并有一些属性和方法设置和操作这些数据。

       比较常用到的属性和方法有:

dropEffect:设置放置操作的类型,可以修改放置时鼠标的显示。比如设置成none,鼠标就会显示成禁止的样式。

effectAllowed:设置拖放过程的操作类型,同样影响鼠标的显示。

setData():设置拖放的数据。一般会在dragstart事件中用到。一个事件中,setData可以设置多个数据。但同类型的数据只能添加一项,重复添加会被最后添加的覆盖。

getData():检索获取拖放的数据。一般会在drop事件中用到。

       具体可以参考MDN文档。

       最后,就是在drop区域中放置拖拽的元素。

       一个代码示例:

function drop_handler(ev) {
  const data = ev.dataTransfer.getData("text/plain");
  ev.target.textContent = data;
}

       这样,拖放就结束了。拖放功能也完成了。

       在拖放过程中,有一些全局事件触发,可以参考下表,具体请查看MDN文档。

事件 触发时刻
drag 当拖拽元素或选中的文本时触发。
dragend 当拖拽操作结束时触发 (比如松开鼠标按键或敲“Esc”键). 
dragenter 当拖拽元素或选中的文本刚进入到一个可释放目标时触发。
dragleave 当拖拽元素或选中的文本离开一个可释放目标时触发。
dragover 当元素或选中的文本被拖到一个可释放目标上时触发(每 100 毫秒触发一次)。
dragstart 当用户开始拖拽一个元素或选中的文本时触发。
drop 当元素或选中的文本在可释放目标上被释放时触发。

一些问题

但是,这样实现拖放功能会有一些体验问题,鼠标的样式显示可能不正确。

以下是一些可能的问题:

1.禁止放置的区域没有显示禁止图标。

在区域上绑定dragover事件,设置dataTransfer.dropEffect='none'并禁止默认行为e.preventDefault()

2.禁止放置的区域可以放置。

通常默认可以放置的区域是一些输入标签,比如<input>、<textarea>。在drop事件中,禁止默认行为e.preventDefault()可以禁止放置。

3.拖拽过程和可放置区域中,鼠标显示禁止图标。

在经过或者放置的区域上,在dragover和dragenter事件中禁止默认行为e.preventDefault(),设置dataTransfernone以外的值。

4.拖拽图片时,鼠标旁边没有出现图片。

要在dragstart事件中,设置dataTransfer为图片类型才会显示一张图片。如果拖拽的不是图片,但是希望拖拽时有拖拽元素的图片效果显示,也可以设置dataTransfer为图片,设置要显示的图片效果,然后再设置其他的数据。dataTransfer.setData()方法是可以设置多个类型的数据的。

         这样拖放功能的实现基本就完善了。最后在开始拖拽和放置的时候,可能会给拖拽元素和放置区域设置一些高亮的css效果,整个拖放功能的体验就会很流畅。

 


参考:

draggable属性:draggable - HTML(超文本标记语言) | MDN (mozilla.org)

拖放API:HTML 拖放 API - Web API | MDN (mozilla.org)

DataTransfer:DataTransfer - Web API | MDN (mozilla.org)

标签:放置,drop,事件,设置,搞懂,拖拽,拖放,dataTransfer
From: https://www.cnblogs.com/-867259206/p/18162266

相关文章

  • RC4Drop加密技术:原理、实践与安全性探究
    第一章:介绍1.1加密技术的重要性加密技术在当今信息社会中扮演着至关重要的角色。通过加密,我们可以保护敏感信息的机密性,防止信息被未经授权的用户访问、窃取或篡改。加密技术还可以确保数据在传输过程中的安全性,有效防止信息泄露和数据被篡改的风险。在网络通信、电子商务、金......
  • 【布局进阶】巧用 :has & drop-shadow 实现复杂布局效果
    最近,群里聊到了一个很有意思的布局效果。大致效果如下所示,希望使用CSS实现如下所示的布局效果:正常而言,我们的HTML结构大致是如下所示:<divclass="g-container"><divclass="g-nav"><ul><li>Tab1</li><li>Tab2</li>......
  • [转帖]性能专题:一文搞懂性能测试常见指标
    https://developer.aliyun.com/article/725602 简介: 1.前言上周,对性能测试系列专题,在公号内发表了第一篇介绍:【性能系列连载一】开篇:性能测试不可不知的“干货”,但反响貌似并不太好,但既然此前已答应了部分读者要连载分享性能这块的知识,含着泪也得继续写。1.前言上周......
  • [深度学习]丢弃法(drop out)
    丢弃法(dropout)一、介绍1.动机一个好的模型需要对输入数据的扰动鲁棒使用有噪音的数据等价于Tikhonov正则丢弃法:在层之间加入噪音2.丢弃法的定义这里除以\(1-p\)是为了\(x_i^{'}\)与原来的\(x_i\)的期望相同。\[0\timesp+(1-p)\times\dfrac{x_i}{1-p}=x_i......
  • 短视频app源码,一文带你轻松搞懂前端大文件上传思路
    短视频app源码,一文带你轻松搞懂前端大文件上传思路文件上传是我们在平时开发短视频app源码中经常会遇到的业务,如果只是简单的文件上传那还不足以作为项目亮点,而当我们给它加上切片、续传的功能,就不一样了。本文会带大家搞明白这些功能的实现思路,主要聚焦于前端部分,基于Vue3......
  • 一文搞懂计算机视觉模型
    计算机视觉,这个曾经让科学家们望而生畏的领域,如今在深度学习的加持下,正迎来前所未有的发展。你是否好奇,是哪些深度学习模型让计算机拥有了“慧眼”?让我们一起揭开这些模型的神秘面纱。/1卷积神经网络(CNNs)。它们就像是视觉任务的万金油,无论是图像分类、目标检测还是人......
  • 【深入理解Java IO流0x07】搞懂Java中的三种IO模型的区别:BIO & NIO & AIO
    1.引言NIO这一块是面试时比较喜欢问的问题,所以我们需要仔细学习。但是在直接讲NIO之前,需要大家对Java的IO模型首先有一个整体的认识,这样才方面后续我们深入探究NIO。我们接下来就开始吧!2.IO何为IO?I/O(Input/Outpu)即输入/输出。我们先从计算机结构的角度来解读一下......
  • 一文搞懂航测成果和3dsmax、sketchup设计软件的交互
    0序BIM+GIS+CAD融合是当下比较热的一个概念。在设计环节,自然是希望能够基于真实的航测成果去做设计(在现状地形的基础上做设计),设计完的成果能够直接导入到GIS平台叠加红线、水系、路网等各种业务数据,做设计方案的校验。同豪、Revit、Microstation、OpenRoads等bim设计软件......
  • 这一次,让我们一起来搞懂MySQL
    欢迎加入我的专栏,和我一起开始 MySQL 学习之旅。从日常的开发和优化中,一步步地从一个数据库小白成为 MySQL 调优的开发人员。回想起来,从我第一次带创建索引至今,已经有十个年头了。在这个过程中,走了不少弯路,但同时也收获了很多的知识和思考,希望能在这个专栏里分享给你。记得......
  • 一文彻底搞懂synchronized实现原理
    文章目录1.synchronized是什么2.synchronized可以实现的锁3.synchronized使用4.synchronized底层原理4.1作用于同步代码块4.2作用于方法1.synchronized是什么synchronized是Java中实现线程同步的关键字,用于保护共享资源的访问,确保在多线程环境中同一......