Back:使用鼠标事件来实现拖放
常见业务场景
- 操作类拖拽:拖拽文件上传
- 功能性拖拽:拖拽排序,具有指向性,位置互换
- 使用方便型:对某些固定元素,使其随处可放
拖放流程
用户通过鼠标选中一个可拖动的(draggable)元素,移动鼠标到一个可放置的(droppable)元素,然后释放鼠标
即:选中 → 拖放 → 释放
可拖动元素
attribute:
<element draggable="true | false | auto"></element>
true
:可以拖动false
:禁止拖动auto
:默认值,跟随浏览器定义是否可以拖动- 图片和链接默认可拖动
- 文本只有在被选中的情况下才能拖放,如果显示设置为
true
也可以直接拖放
这个 attribute 是枚举类型,而不是布尔类型。这意味着必须显式指定值为字符串,像 <img draggable>
这样的简写是不允许的
property:
elem.draggable: boolean
注意:只有 draggable
(是否可拖动),没有 droppable
(是否可被当成拖动目标)
拖放事件
被拖动的元素(draggable):
dragstart
:开始拖动元素或被选择的文本drag
:拖动过程中持续触发(每几百毫秒触发一次)dragend
:拖放操作结束(通过释放鼠标按钮或单击 escape 键)- 此事件不可取消
目的地元素(droppable):
dragenter
:被拖动元素进入目的地元素所占据的屏幕空间dragover
:被拖动元素在目的地元素内持续触发(每几百毫秒触发一次)dragleave
:被拖动元素没有放下就离开目的地元素- 此事件不可取消
drop
:被拖动元素在目的地元素内释放鼠标- 为确保
drop
事件始终按预期触发,应当在处理dragover
事件的代码部分始终包含preventDefault()
调用 - 如果从外部拖拽图片等文件,需要阻止默认行为,不然浏览器默认会打开
- 为确保
DataTransfer 对象
DragEvent 派生于 MouseEvent,并增加了 dataTransfer
属性。该属性用于保存拖放的数据和交互信息,返回 DataTransfer 对象:
effectAllowed: string
:拖放操作所允许的效果(影响鼠标显示的类型)- 应该在
dragstart
事件中设置此属性,以便为拖动源设置所需的拖动效果 - 在
dragenter
和dragover
事件处理程序中,该属性将设置为在dragstart
事件期间分配的任何值,可以使用effectAllowed
来确定允许哪个效果 - 取值:
none
:不允许放下copy
:源项目的复制项可能会出现在新位置(还与dropEffect
设置的值相关)link
:可以在新地方建立与源的链接(还与dropEffect
设置的值相关)move
:源项目可能被移动到新位置(还与dropEffect
设置的值相关)copyLink
:允许copy
或link
操作copyMove
:允许copy
或move
操作linkMove
:允许link
或move
操作all
:允许所有的操作uninitialized
:默认值,等同于all
- 其他值:无效,保留原值
- 应该在
dropEffect: string
:目标区域的效果(影响鼠标显示的类型)- 对于
dragenter
和dragover
事件,会根据用户的请求行为进行初始化。具体如何初始化和浏览器平台有关,但是通常来讲,用户可以通过按住修改键(比如 Alt)来修改想要的行为。 - 对于
drop
和dragend
事件,会被设置为想要得到的值,即最后一次dragenter
或dragover
事件后dropEffect
的值。例如,在一个dragend
事件中,如果期望得到的dropEffect
是move
,那么被拖拽的数据会从源中移除 - 取值:
none
:项目可能禁止拖放(还与effectAllowed
设置的值相关)copy
:在新位置生成源项的副本move
:将项目移动到新位置link
:在新位置建立源项目的链接- 其他值:无效,保留原值
- 对于
files: FileList
:拖动操作中的文件列表FileList
。如果操作不包含文件,则此列表为空- 此功能可用于将文件从操作系统拖动到浏览器
items: DataTransferItemList
:只读,拖动操作中 数据传输项(DataTransferItem
) 的 列表(DataTransferItemList
)。该列表包含了操作中每一项目的对应项,如果操作没有项目,则列表为空- 文件会自动放在里面
DataTransferItem.kind
:只读,拖拽项的种类"file"
:拖动数据项是文件"string"
:拖动数据项是纯文本的 Unicode 字符串
DataTransferItem.type
:只读,拖拽项的类型,一般是一个 MIME 类型DataTransferItem.getAsFile(): File | null
DataTransferItem.getAsString(callback)
:使用拖拽项的字符串作为参数执行指定回调函数
types: string[]
:只读,字符串数组,与items
一一对应(表示items[i]
的类型)Files
或 MIME 类型- 如果是
setData(type, data)
,就是key
setData(type: string, data: string)
:在items
和types
中添加数据type
在items
中不存在:在items
和types
末尾添加type
在items
中存在:items
对应值更新,types
不修改
getData(type: string): string
:获取setData
的值clearData(type?: string)
:删除items
的值type
不传或传空串:清空- 否则删除对应
type
数据
setDragImage(image: Element, x: number, y: number)
- 发生拖动时,从拖动目标 (
dragstart
事件触发的元素) 生成半透明图像,并在拖动过程中跟随鼠标指针。如果想要设置为自定义图像,使用DataTransfer.setDragImage()
方法 - 通常在
dragstart
事件处理程序中调用此方法 image
:通常是<image>
元素,但也可以是<canvas>
或任何其他图像元素x/y
:图像应该相对于鼠标指针出现的偏移量
- 发生拖动时,从拖动目标 (