浅尝HTML5拖拽

  1. 当用户开始拖动一个元素或者一个选择文本的时候 dragstart 事件就会触发

    dragstart - Web API | MDN

    一个元素可被拖动的方式是增加draggable属性,捕获到拖拽行为后会触发dragstart事件,在dragstart的事件对象中,有dataTransfer属性,其中有一个setData(format, data)方法,可以作为拖拽事件传递参数的方法,format可接受的参数是’text/plain’和’text/url-list’

    DataTransfer.setData() - Web API | MDN

    ※ 需要注意的是,被传递的参数data在dragover、dragleave、dragend、dragenter等事件中不可读,在drop事件中可读

    dataTransfer.getData()在dragover,dragenter,dragleave中无法获取数据的问题
  2. 添加了drop和dragover事件的元素可以接受拖动,此时可能由于浏览器的默认事件的限制,drop事件没有被触发,因此在添加了drop事件的元素上监听dragover事件的监听,在其中阻止默认事件,如下:\
1
2
3
4
5
6
7
8
9
10
<div @drop="drop" @dragover="dragover">something</div>
<script>
dragover(e) {
e.preventDefault()
}
drop(e) {
console.log(e.dataTransfer.getData('text/plain')
// do other thing
}
</script>

   需要注意的是,dragenter事件中阻止默认事件并不能有效恢复drop事件的触发

  1. 另外,由于setData的format限制,需要传递纯字符串,使用JSON.stringify的时候其不可以传递有引用自身的对象,因此需要别的方法来传递拖拽数据。或者,如下处理对象,见 处理TypeError: Converting circular structure to JSON
1
2
3
4
5
6
7
8
9
10
11
12
const cache = []
var o = {}
o.o = o
JSON.stringify(o, function(key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
return
}
cache.push(value)
}
return value
})

   经过处理的对象不一定可以满足使用场景

详细文档

HTML 拖放 API - Web API 接口参考 | MDN