前言
最近在做一个音乐播放器,里面想玩几个骚操作,其中有个子功能是拖动文件,特总结一下。
相关事件
先来介绍一下相关的事件
在拖放的过程中会触发以下事件:
以下是拖拽产生的一系列事件,拖拽事件产生时不会产生对应的鼠标事件.
- dragstart:拖拽开始时在被拖拽元素上触发此事件,监听器需要设置拖拽所需数据,从操作系统拖拽文件到浏览器时不触发此事件.
- dragenter:拖拽鼠标进入元素时在该元素上触发,用于给拖放元素设置视觉反馈,如高亮
- dragover:拖拽时鼠标在目标元素上移动时触发.监听器通过阻止浏览器默认行为设置元素为可拖放元素.
- dragleave:拖拽时鼠标移出目标元素时在目标元素上触发.此时监听器可以取消掉前面设置的视觉效果.
- drag:拖拽期间在被拖拽元素上连续触发
- drop:鼠标在拖放目标上释放时,在拖放目标上触发.此时监听器需要收集数据并且执行所需操作.如果是从操作系统拖放文件到浏览器,需要取消浏览器默认行为.
- dragend:鼠标在拖放目标上释放时,在拖拽元素上触发.将元素从浏览器拖放到操作系统时不会触发此事件.
不过我只用了ondragover和ondragend还有ondrop
值得注意的一点
使用这些事件实现拖动文件(项目中是拖动音频文件到指定区域)的时候要记住使用event.preventDefault()。
chrome浏览器的drop事件的默认行为是打开被放到放置目标上的URL。为了让chrome支持正常的拖放,还要取消drop事件的默认行为,不过实现的时候我必须要在dragover上也加preventDefault才行,应该是dragover也有默认行为是打开url吧,知道的读者请回复告知我。
DataTransfer对象
DataTransfer
先上MDN
总的来说就是拖动完后可以通过这个对象获取数据信息。
核心属性
比较核心的属性是files包含一个在数据传输上所有可用的本地文件列表。如果拖动操作不涉及拖动文件,此属性是一个空列表。此属性访问指定的FileList
中无效的索引将返回未定义(undefined)。
一个奇怪的情况
先上代码
// vue里面事件绑定,绑定drop事件
@drop.prevent="uploadMusic($event)"
...
uploadMusic(event) {
let self = this
console.dir(event)
console.dir(event.dataTransfer)
console.dir(event.dataTransfer.files[0])
let file = event.dataTransfer.files[0]
...
},
很迷的情况是我console.dir(event.dataTransfer)时files为空数组length为0
然而我event.dataTransfer.files[0]结果却有。很奇怪啊,请知道的读者留言告诉我怎么回事。
DataTransfer的其他方法(待补充)
反正现在只用到了dataTransfer里面的files,获取从操作系统拖曳出来的文件。event.dataTransfer.files[0]
实战 (联动)
现在我们做一个demo吧,拖曳音乐到指定区域,然后播放出音乐来。
联动
Audio对象(梁王的理论自习室)(未完成)
音乐拖动上传播放(梁王的开发笔记)(未完成)