首页 > 代码库 > Html5学习之拖放操作详解

Html5学习之拖放操作详解

在html5页面开发中,拖放操作里面非常重要的一个点就是,我们要确定哪里发生了拖放事件。顾名思义,拖放事件,就是有脱(drag)事件和放(drop)事件。

拖放操作里面非常重要的一个点就是,我们要确定哪里发生了拖放事件。顾名思义,拖放事件,就是有脱(drag)事件和放(drop)事件。

当某个元素被拖动的时候,在这个元素上将被依次触发以下事件:

1. dragstart

2. drag

3. dragend

按下鼠标键并开始移动鼠标时,就会在被拖动元素上触发 dragstart 事件,随机触发 drag 事件, drag 事件会在鼠标移动的过程中不断被触发,当拖动停止,无论是把元素放置到有效的目标还是无效的目标上,都会触发 dragend 事件。

tip:在元素被拖动期间,大多数浏览器会为正在被拖动的元素创建一个半透明的副本,这个副本始终随着光标移动。

当某个元素被拖动到一个有效的放置目标上,下列事件又会依次发生:

1. dragenter

2. dragover

3. dragleave 或 drop

只要有元素被拖动到放置目标上,就会触发 dragenter 事件,随即会触发 dragover 事件,在被拖动元素在目标元素上移动的时候会不断触发 dragover 事件,如果元素移出了目标元素就会触发 dragleave 事件,如果元素被放置到目标元素中则会触发drop 事件。

自定义放置目标

有些元素默认是不允许放置的,当我们拖动的元素放置到无效的放置目标上,会发生什么事呢?其实也没什么事会发生,就是无论用户如何操作,都不会发生 drop 事件。

但是我们可以将它设置为可以被放置的。重写 dragenter 和 dragover 事件的默认行为就可以将目标设置为可以被放置的了。

let dropTarget = document.getElementById(’target’)

dropTraget.addEventListener(’dragenter’, e => {

e.preventDefault()

}, false)

dropTraget.addEventListener(’dragover’, e => {

e.preventDefault()

}, false)

dataTransfer 对象

现在我们把目标设置为可放置的,但是当我们把元素拖到目标上面放下的时候,依然什么事情都没有发生,这就对了

,因为把元素放到可放置的目标上只是触发了 drop 事件

,就是什么事都没有发生。

所以,我们需要实现数据的交互。这个时候,我们就要用到 dataTransfer 这个对象。 dataTransfer 是一些列拖放事件的事件对象里的一个属性( e.dataTransfer)。

数据通信

dataTransfer 主要有两个方法, getData 和 setData 

这两个方法有什么作用呢?举个栗子:你可以在 A 元素被拖动的时候设置数据

e.dataTransfer.setData(’text’, ’I\’m A!!!’)

然后在目标 B 的 drop 事件中可以获取到这个数据

e.dataTransfer.getData(’text’) // I’m A!!!

这样就可以实现拖拽元素和目标元素之间的通信了。

这两个方法使用起来要注意的问题挺多,具体的请看 文档

dropEffect 和 effectAllowed

利用 dataTransfer 的 dropEffect 和 effectAllowed 这两个属性可以控制被拖动元素做什么操作,以及放置目标元素接收什么操作。

其中, dropEffect 属性可以知道被拖动元素能够执行哪种放置行为,是把元素复制到目标元素,还是直接移动到元素…。这个属性可以被设置为以下 个值:

· none :不能把拖动的元素放到目标

· move :应该把拖动的元素移动到目标

· copy :应该把拖动的元素复制到目标

· link :放置目标会打开拖动的元素(拖动的元素必须是一个链接,有 URL

dropEffect 必须在 dragenter 事件中设置

effectAllowed 是和 dropEffect 协同工作的,表示允许被拖动元素的哪种 dropEffect

· uninitialized :没有给被拖动的元素设置任何放置行为

· none :被拖动元素不能有任何行为

· copy :只允许值为 copy 的 dropEffect

· move :只允许值为 move 的 dropEffect

· copyLink :只允许值为 copy/link 的 dropEffect

· copyMove :只允许值为 copy/move 的 dropEffect

· linkMove :只允许值为 link/move 的 dropEffect

· all :允许任意的 dropEffect

effectAllowed 必须在 dragstart 事件中设置

天真的我曾经以为,把 dropEffect 设置为 move ,把 effectAllowed 设置为 move 。拖动元素的时候,浏览器就会替我去操作DOM,改变被拖动元素的位置了。而事实上,什么都不会发生,刚开始的时候很是令人费解~~~

经过我一番测试, dropEffect 和 effectAllowed 配对如果成功的话,那么 drop事件就会被触发,否则,就不会。

来源:Mertens Notes

Html5学习之拖放操作详解