JavaScript原生拖放详解
作者:橘猫吃不胖~
本文介绍了HTML5拖放事件的处理方法,包括拖放事件的触发顺序、dataTransfer对象的使用以及可拖动能力的设置,通过这些方法,可以实现更丰富的用户交互效果
拖放事件
拖放事件可以让开发者控制拖放操作的方方面面,关键的部分是确定每个事件是在哪里触发的,有的事件在被拖放元素上触发,有的事件则在放置目标上触发。
当某个元素被拖动时,会按顺序触发以下事件:
事件 | 说明 |
---|---|
dragstart | 按住鼠标不放开始移动鼠标时触发 |
drag | 元素正在被拖动时触发 |
dragend | 停止拖动时触发 |
在把元素拖动到一个有效的放置目标上时,会依次触发以下事件:
事件 | 说明 |
---|---|
dragenter | 被拖动的元素进入目标容器时触发 |
dragover | 被拖拽元素在目标容器内拖动时触发 |
dragleave | 被拖动元素离开目标容器时触发 |
drop | 被拖动元素放到了目标容器上触发 |
如果我们想让一个元素可以被拖放,还要为该元素添加dragabble
属性
dataTransfer对象
dataTransfer
对象实现了拖动操作中的数据传输,用于从被拖动元素向放置目标传递字符串数据。
因为这个对象是event
的属性,所以在拖放事件的事件处理程序外部无法访问dataTransfer
。
该对象内部有以下属性和方法:
事件 | 说明 |
---|---|
dropEffect | 可以告诉浏览器允许哪种放置行为,获取当前选定的拖放操作类型或者设置的为一个新的类型。值必须为none, copy, link、move。 |
effectAllowed | 表示对被拖动元素是否允许dropEffect,提供所有可用的操作类型。必须是none, copy, copyLink, copyMove, link, linkMove, move, all、uninitialized之一。 |
files | 包含数据传输中可用的所有本地文件的列表。如果拖动操作不涉及拖动文件,则此属性为空列表。 |
items | 提供一个包含所有拖动数据列表的DataTransferItemList对象。 |
types | 一个提供dragstart事件中设置的格式的strings数组。 |
clearData() | 删除与给定类型关联的数据。类型参数是可选的。如果类型为空或未指定,则删除与所有类型关联的数据。如果指定类型的数据不存在,或者data transfer中不包含任何数据,则该方法不会产生任何效果。 |
getData() | 检索给定类型的数据,如果该类型的数据不存在或data transfer不包含数据,则返回空字符串。 |
setData() | 设置给定类型的数据。如果该类型的数据不存在,则将其添加到末尾,以便类型列表中的最后一项将是新的格式。如果该类型的数据已经存在,则在相同位置替换现有数据。 |
setDragImage() | 用于设置自定义的拖动图像。 |
可拖动能力
HTML5
在所有HTML
元素上规定了一个draggable
属性,表示元素是否可以拖动。
图片和链接的draggable
属性自动被设置为true
,而其他所有元素此属性的默认值为false
。
如果想让其他元素可拖动,或者不允许图片和链接被拖动,都可以设置这个属性。
示例代码:
<!-- 禁止拖动图片 --> <img src="smile.gif" draggable="false" alt="Smiley face"> <!-- 让元素可以拖动 --> <div draggable="true">...</div>
一个拖动demo
设置一个可以拖拽的元素:
<div id="draggable" draggable="true">Drag me!</div>
#draggable { width: 100px; height: 100px; background-color: #3498db; color: #fff; text-align: center; line-height: 100px; cursor: move; position: absolute; }
const draggableElement = document.getElementById('draggable'); let offsetX, offsetY; draggableElement.addEventListener('dragstart', function (event) { // 拖动开始时计算鼠标位置与元素左上角的偏移,并记录 offsetX = event.clientX - draggableElement.getBoundingClientRect().left; offsetY = event.clientY - draggableElement.getBoundingClientRect().top; }); draggableElement.addEventListener('drag', function (event) { // 计算元素应该移动到的位置 const x = event.clientX - offsetX; const y = event.clientY - offsetY; // 更新元素位置 draggableElement.style.left = x + 'px'; draggableElement.style.top = y + 'px'; }); draggableElement.addEventListener('dragend', function (event) { const x = event.clientX - offsetX; const y = event.clientY - offsetY; // 拖动结束之后更新元素的位置 draggableElement.style.left = x + 'px'; draggableElement.style.top = y + 'px'; });
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。