博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HTML5新增的拖放API
阅读量:4149 次
发布时间:2019-05-25

本文共 3589 字,大约阅读时间需要 11 分钟。

HTML5新增了关于拖放的API,通过拖放API可以让HTML页面的任意元素都变成可拖动的,通过使用拖放机制可以开发出更友好的人机交互界面。拖放操作可以分成两个动作:在某个元素上按下鼠标并移动鼠标(没有松开鼠标),此时开始拖动;在拖动过程中,只要没有松开鼠标,将会不断地产生拖动事件——这个过程被称为拖;把被拖动的元素拖动到另外一个元素上并松开鼠标——这个动作被称为放。拖放操作由拖和放两个动作组成。

浏览器支持

Internet Explorer 9、Firefox、Opera 12、Chrome 以及 Safari 5 支持拖放。

1.启动拖动

在HTML5中,<img/>元素默认就是可拖动的;而<a/>元素只要设置了href属性,它默认也是可拖动的。

	
可拖动 百度一下百度一下

对于普通元素而言,如果希望把它变成可拖动的,我们只要把该元素的draggable属性设为true即可。但仅仅设置该元素的draggable属性还不够,因为仅仅设置了draggable=true只表示该元素可拖动,但拖动时并未携带数据,因此用户看不到拖动效果。为了让拖动操作能携带数据,应该为被拖动元素的ondragstart事件指定监听器,在该监听器中让拖动操作可以携带数据。例如下面代码所示。

	
可拖动的Div
百度一下

2.接受放的操作

不管是拖动图片,还是拖动<div/>元素,拖动时都显示了一个禁止标志,这表明拖动图片、拖动<div/>时,被拖到目的地并不接受被拖动的元素——这是因为当被拖动元素被拖过document对象时,document对象默认阻止了拖动事件,而其他HTML组件也是位于document对象内的,因此它们也不能接受放。为了让document可以接受放,应该为document的ondragover事件指定监听器,在监听器中取消document对拖动事件的默认行为。

注意:当我们把<div/>元素拖到指定位置释放后,Firefox浏览器默认会打开一个新页面,页面的URL正是拖放操作携带的数据。但如果使用Chrome浏览器来浏览该页面,当我们把<div/>元素拖到指定位置释放后,Chrome浏览器并没有执行任何默认动作。

由此可见,不同浏览器对于拖放操作的默认动作并不相同,如果开发者希望取消拖放操作的默认动作,则可以为document的ondrop事件绑定监听器。也就是再增加如下代码。

	
可拖动的Div
百度一下

在我们拖放HTML元素的过程中,可能触发如下表所示的事件。

事件 事件源 描述
ondragstart 被拖动的HTML元素 开始拖动时触发该事件
ondrag 被拖动的HTML元素 拖动过程中会不断的触发该事件
ondragend 被拖动的HTML元素 拖动结束时触发该事件
ondragenter 拖动时鼠标经过的元素 被拖动的元素进入本元素范围内时触发该事件
ondragover 拖动时鼠标经过的元素 被拖动的元素进入本元素范围内拖动时会不断的触发该事件
ondragleave 拖动时鼠标经过的元素 被拖动的元素离开本元素时触发该事件
ondrop 拖动时鼠标经过的元素 其他元素被放到本元素中时触发该事件

如果希望实现一个允许自由拖动的<div/>,这就比较简单了——只要监听document的ondrop方法,当用户把<div/>元素放到document中时,通过JavaScript代码把该元素移动到该位置即可。下面代码实现了一个可以自由拖动的<div/>元素。

	
可自由拖动的Div
百度一下

上面代码把<div/>元素的left属性设为evt事件发生点的X坐标,top属性设为evt事件发生点的Y坐标,这样就可以把<div/>元素移动到指定位置。

3.DataTransfer对象

拖放触发的拖放事件有一个dataTransfer属性,该属性值是一个DataTransfer对象,该对象包含如下属性和方法。

属性和方法 描述
dataTransfer.dropEffect 设置或返回拖放目标上允许发生的拖放行为。如果此处设置的拖放行为不在effectAllowed属性设置的多种拖放行为之内,拖放操作将会失败。该属性值只允许为none、copy、link和move四个值之一。
dataTransfer.effectAllowed 设置或返回被拖动元素允许发生的拖动行为。该属性值可设置为none、copy、copyLink、copyMove、link、linkMove、move、all和uninitialized。
dataTransfer.items 该属性返回DataTransferItems对象,该对象代表了拖动数据。
dataTransfer.setDragImage(element, x, y) 设置拖放操作的自定义图标。其中element设置自定义图表,x设置图标与鼠标在水平方向的距离;y设置图标与鼠标在垂直方向的距离。
dataTransfer.addElement(element) 添加自定义图标。
dataTransfer.types 该属性返回一个DOMStringList对象,该对象包括了存入dataTransfer中数据的所有类型。
dataTransfer.getData(format) 获取DataTransfer对象中format格式的数据。
dataTransfer.setData(format, data) 向DataTransfer对象中设置format格式的数据。其中format代表数据格式,data代表数据。
dataTransfer.clearData([format]) 清除DataTransfer对象中format格式的数据。如果省略format格式,则意味着清除DataTransfer对象中的全部数据。

通过DataTransfer对象,可以让拖放操作实现更丰富的功能——我们可以在拖放开始时(ondragstart事件)将拖放源的数据存入DataTransfer对象中,然后在拖放结束时从DataTransfer对象中读取数据,这样就可以完成更复杂的拖放操作了。下面代码实现了一个允许通过拖放来添加、删除收藏项的功能。

	
通过拖放实现添加、删除

可将喜欢的项目拖入收藏夹

11111111111
22222222222
33333333333
44444444444

收藏夹

垃圾桶

4.拖放行为

通过设置DataTransfer对象的effectAllowed、dropEffect两个属性可以控制拖放行为。effectAllowed用于控制被拖动元素的拖动行为,因此通常建议在ondragstart事件监听器中设置DataTransfer对象的effectAllowed属性;而dropEffect则控制被“放”入的目标组件的行为,因此通常建议在ondragover事件监听器中设置DataTransfer对象的dropEffect属性。如果dropEffect设置的拖放行为不在effectAllowed属性设置的多个拖放行为之内,拖放操作将会失败。具体来说,需要注意如下4点:

  1. 如果effectAllowed设为none,则不允许拖动该元素。
  2. 如果dropEffect设置为none,则被拖动的元素不能“放”到本元素中。
  3. 如果effectAllowed设置为all或不设置,则dropEffect可设置为任何属性值(因为都在all范围之内),而且将会遵守dropEffect指定的拖放行为。
  4. 如果effectAllowed指定了特定的拖放行为,例如move、copy等,那么dropEffect指定的属性值必须是effectAlllowed指定的多个属性值的子集。

下面代码示范了修改effectAllowed属性的效果。

	
拖放行为
拖动我

5.改变拖放图标

通过调用DataTransfer对象的setDragImage还可以改变拖放图标,例如,把上一个例子的JavaScript脚本改为如下形式。my.gif图片自己添加一个放到同级目录即可。

	
拖放行为
拖动我

 

------------如果大家喜欢我的博客,可以点击左上角的关注哦。

转载地址:http://ufpti.baihongyu.com/

你可能感兴趣的文章
Timestamping Linux kernel printk output in dmesg for fun and profit
查看>>
There's Much More than Intel/AMD Inside
查看>>
CentOS7 安装MySQL 5.6.43
查看>>
使用Java 导入/导出 Excel ----Jakarta POI
查看>>
本地tomcat 服务器内存不足
查看>>
IntelliJ IDAE 2018.2 汉化
查看>>
基于S5PV210的uboot移植中遇到的若干问题记录(一)DM9000网卡移植
查看>>
Openwrt源码下载与编译
查看>>
我和ip_conntrack不得不说的一些事
查看>>
Linux 查看端口使用情况
查看>>
文件隐藏
查看>>
两个linux内核rootkit--之二:adore-ng
查看>>
两个linux内核rootkit--之一:enyelkm
查看>>
关于linux栈的一个深层次的问题
查看>>
rootkit related
查看>>
配置文件的重要性------轻化操作
查看>>
又是缓存惹的祸!!!
查看>>
为什么要实现程序指令和程序数据的分离?
查看>>
我对C++ string和length方法的一个长期误解------从protobuf序列化说起(没处理好会引起数据丢失、反序列化失败哦!)
查看>>
一起来看看protobuf中容易引起bug的一个细节
查看>>