阅读 115

drag 和 drop实现拖拽效果

背景:前几日,有小伙伴问我如何实现物体的拖拽,当时的回答即 onMouseDown、onMouseMove 和 onMouseUp 事件结合起来做。小伙伴当时觉得这么实现非常的麻烦,于是我又提供了另外一种思路,即通过 drag 和 drop 来实现此效果。

drag、drop 是什么

dragdrop 是一个 API,它可以让页面中的绝大部分元素都变得可拖拽,比如,用户可以通过鼠标选择可拖拽元素,将元素拖拽到可放置元素上,并释放鼠标以便放置这些元素。拖拽期间,会有一个拖拽元素的半透明快照跟随鼠标指针。默认情况下,只有图片、链接、选择的文本可以被拖拽。如果想要其他元素可拖拽,则需要在元素上设置 draggable=true

<div draggable="true">这是一个可拖拽的元素</div> 复制代码

当拖拽事件发生时,被拖拽的元素会依次触发 onDragStartonDragonDragEnd,可放置元素会触发 onDragEnteronDragOveronDrop 事件,当被拖拽的元素离开可放置元素上方,还会触发 onDragLeave 事件。 如果想把元素放置到可放置元素上,需做如下设置。如果不设置,则可放置元素的 onDrop 事件无法触发。

const onDragEnter = useCallback((e: React.DragEvent) => { e.preventDefault(); }, []); const onDragOver = useCallback((e: React.DragEvent) => { e.preventDefault(); }, []); 复制代码

到此,我们已经可以拖动元素,也可以让元素接收到 onDrop 事件。

传递数据

每一个拖拽事件都有 dataTransfer 对象,可以通过对象上的 setData 方法存储拖拽数据。拖拽数据主要包含两个信息,数据的类型和数据值。一般都会在 onDragStart 事件中存储拖拽数据,在 onDrop 事件中读取数据。使用方法如下:

const onDragStart = useCallback((e: React.DragEvent, item) => { e.dataTransfer.setData('text/plain', '这是一个可拖拽的元素'); }, []); const onDrop = useCallback((e: React.DragEvent, item) => { const data = e.dataTransfer.getData('text/plain'); ... }, []); 复制代码

dataTransfer  对象上 files 属性通常存储从桌面往浏览器中拖拽的文件列表,目前的应用场景大多为拖拽上传。每一个文件上都包含 3 个字段:namesizetype。 当发生拖动时,浏览器会自动生成一个半透明的图像,并在拖拽过程中跟随鼠标。

DataTransfer 还支持哪些场景

上文所述的大部分拖拽场景都是在同一个浏览器,如果当前需求是把某一个元素从 A 浏览器拖拽到 B 浏览器某一位置,那么我们应该怎么实现呢?乍一看,这样的需求貌似是无法实现的,但是我们使用dataTransfer就可以做到。如果你想做跨浏览器的拖拽,唯一需要注意的是拖拽数据的类型,现在大部分的应用程序均支持 text/htmltext/plaintext/uri-list。当然,你也可以使用自定义拖拽数据的类型。

  • text/html:在 contentEditable 的元素中渲染数据。

  • text/plain:作为代码编辑器的内容、input 元素标签的 value

  • text/uri-list:放置在浏览器中,会导航到 URL;如果放置于桌面,则会创建快捷方式。

总结

本文主要讲解 dragdrop 的应用,也介绍可以利用这两个 API 可以实现跨浏览器的拖拽。当然,如果你对上述跨端的拖拽场景感兴趣的话,也可以尝试下 Transmat 库,这个库主要简化了在 Web 应用程序中传输和接收数据的过程。


作者:时间小鱼
链接:https://juejin.cn/post/7025873834901241869


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐