liubulong 发表于 2019-11-26 11:52:19

浅谈基于html5的拖拽

近期有个项目需要用到拖拽功能,找了很多相关这方面的资料研究,经过一番折腾,最终简单的写了个DEMO,现将使用过程中的问题和解决办法分享如下,希望对新手同事有帮助。Drag 的使用门槛还是相当低的,基本上只要知道什么时候触发什么事件就行了,因此这篇主要也像是过一遍 API。HTML5提供专门的拖拽与拖放的API,以后实现这类效果就不必乱折腾了。但是,考虑到Opera浏览器似乎对此不感冒,在通用性上有待商榷,所以这里也就简单说一说。
相关API如下:
DataTransfer 对象:退拽对象用来传递的媒介,使用一般为Event.dataTransfer。
draggable 属性:就是标签元素要设置draggable=true,否则不会有效果,例如:
<div title="拖拽我" draggable="true">列表1</div>
ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上
ondragenter 事件:当拖曳元素进入目标元素的时候触发的事件,此事件作用在目标元素上
ondragover 事件:拖拽元素在目标元素上移动的时候触发的事件,此事件作用在目标元素上
ondrop 事件:被拖拽的元素在目标元素上同时鼠标放开触发的事件,此事件作用在目标元素上
ondragend 事件:当拖拽完成后触发的事件,此事件作用在被拖曳元素上
Event.preventDefault() 方法:阻止默认的些事件方法等执行。在ondragover中一定要执行preventDefault(),否则ondrop事件不会被触发。另外,如果是从其他应用软件或是文件中拖东西进来,尤其是图片的时候,默认的动作是显示这个图片或是相关信息,并不是真的执行drop。此时需要用用document的ondragover事件把它直接干掉。
Event.effectAllowed 属性:就是拖拽的效果。
用原生 JS 实现了以下效果:

代码解释:

调用 preventDefault() 来避免浏览器对数据的默认处理(drop 事件的默认行为是以链接形式打开)
通过 dataTransfer.getData("Text") 方法获得被拖的数据。该方法将返回在 setData() 方法中设置为相同类型的任何数据。
被拖数据是被拖元素的 id
把被拖元素追加到放置元素(目标元素)中
首先,初始化,我们把数据和 DOM 之间的关系建立在初始化和改变中,通过数据生成 DOM ,通过 DOM 的 index 去找到对应的 item。
我们要求列表的每一项都是可拖动的,所以每个 li 元素的 draggable="true"。
然后注册事件,事件我们统一的绑定在面板(panel)上,利用事件冒泡的效果比较好一点,虽然在数量比较少的情况下其实是无所谓的。
对于要进行拖拽的数据,我们绑定 drag(包括了从 dragstart 到 dragend 一系列),对于目标位置,我们使用 drop 来处理拖拽放置的结果,特别的是 dragover 是用于允许 drop 的,需要避免浏览器
的默认事件,需要做 preventDefault() 处理。
在所有事件中,我们都能从 event.dataTransfer 中存取 data,操作方式和其他存储结构并没有什么本质的区别,并且只能是 String。这里我们为了实现 DOM 和 数组的关联存了一些必须品。
在 drop 中,就只剩下插入 DOM 和交换数据两个主要职能了。写完这个之后发现了一个叫做Element.insertAdjacentHTML(),深表 Amazing。当时用的还是很 Low 的 insertBefore 和
appendChild,所以交互并不是很好。

liubulong 发表于 2019-11-26 11:52:34

666666666666
页: [1]
查看完整版本: 浅谈基于html5的拖拽