关于拖放最有意思的可能就是可以跨窗格、跨浏览器容器、有时候甚至可以跨应用程序拖动元素 ——红宝书
<body>
<img src="https://www.baidu.com/img/dong_f17b19f600dbf0bfc9b8bed5836f50be.gif" class="drag-source"/>
<div class="drop-target"></div>
</body>
以下均基于上述代码
拖动过程
拖放事件
触发对象 | 事件名称 | 描述 |
---|---|---|
被拖动元素 | dragstart | 开始被拖动时触发 |
drag | 拖动过程中持续 触发 | |
dragend | 拖动结束时触发 | |
放置目标元素 | dragenter | 开始进入放置目标时触发 |
dragover | 进入放置目标中持续 触发 | |
dragleave | 离开放置目标时触发 | |
drop | 在放置目标释放元素时触发 |
可拖动能力
HTML5 在所有html元素上规定了一个draggable
属性,可通过改变draggable属性值来控制元素是否可被拖动。 默认情况下,图片、链接和文本的draggable值true,其中文本
在被选中后才可拖动,而图片
、链接
在任何时候都可拖动。
可放置目标
所有元素都支持放置目标事件,但是这些元素默认
是不可放置
的。可通过在放置目标上,阻止默认行为
,将其转换为有效的放置目标。只有有效的可放置目标,才会触发相应的drop事件。
const dropTarget = document.querySelector('.drop-target');
dropTarget.addEventListener('dragenter', function (e) {
e.preventDefault();
});
dropTarget.addEventListener('dragover', function (e) {
e.preventDefault();
});
dataTransfer 对象
dataTransfer对象是为解决拖动过程中数据传输
需求而生的,该对象是event对象的一个属性,因此在拖放事件外部
无法访问dataTransfer对象。其拥有两个主要方法:setData()和getData();
- setData(dataType, dataValue)
dataType 为设置的数据类型,包括任何
MIME
类型, 例如: text/plain、text/url-list等,IE中的text和URL类型会分别映射
为text/plain, text/url-list - getData(dataType) 获取dataTransfer对象中相应数据类型的数据值
dataTransfer 对象可以分别
保存各种数据类型的一个值,数据之间不会相互覆盖。拖动文本时,浏览器会自动调用setData以text的格式,存储起来。拖动图片、链接时,会自动调用setData以URL的格式存储起来。
作为URL格式存储时,数据会被当作网页中的一个链接🔗,如果将其拖到另一个浏览器窗口的话,会自动导航到该URL
dropEffect和effectAllowed属性
dataTransfer不仅可以进行简单的数据传输,也可以通过其dropEffect和effectAllowed两个属性,确定对被拖动元素和放置目标执行什么操作。
-
dropEffect 属性告诉浏览器允许哪种放置行为,有且仅有以下4个值。
- none: 被拖动元素不能放置在这
默认
- move: 被拖动元素应该移动到放置目标
- copy: 被拖动元素应该复制到放置目标
- link: 放置目标会导航到被拖动元素(仅在它是URL的情况下) 在把元素拖动到放置目标上时,上述每种值都会导致一种指示光标,但仅仅只是光标会自动变化,如果没有代码的参与,则不会自动移动、复制或链接。
- none: 被拖动元素不能放置在这
-
dropEffect 是否生效还需取决于设置的effectAllowed属性的值,effectAllowed 表示
被拖动元素
允许的行为。包括以下属性值:- uninitialized: 没有给被拖动元素设置允许的动作
- none: 被拖动元素没有被允许的动作
- copy: 允许
copy
这种dropEffect - move: 允许
move
这种dropEffect - link: 允许
link
这种dropEffect - copyLink: 允许
copy
和link
两种dropEffect - copyMove: 允许
copy
和move
两种dropEffect - linkMove: 允许
link
和move
两种dropEffect - all: 允许所有的dropEffect(默认)
dataTransfer对象的其他成员
- clearData(format) 清除以特定格式存储的数据,如果format未指定,则清除所有格式数据
- setDragImage(element, x, y) 设置自定义的拖动图像, element 为显示的半透明图片
总结
虽然已经有了许多优秀的库,能够帮助开发者实现复杂的拖放效果,但是了解原生实现也不容忽视。如有错误或不严谨的地方,欢迎批评指正。如果喜欢,欢迎点赞、收藏。