HTML5 — 让拖放变的流行起来

2022-11-24 0 617

(点选下方,可加速高度关注)

译者:佩列莫加迟

邮箱:http://www.cnblogs.com/zichi/p/5080147.html

先上 Demo(http://hanzichi.github.io/demo/drag/index.htm),尽可能用 chrome,标识符可参照 Github。

在 HTML5 再次出现以后,网页原素的分页须要窃听 mousedown、mouseover 和 mouseup 等一连串该事件,接着发生改变原素的相较边线来同时实现而此效用。HTML DnD(Drag-and-Drop)API 的再次出现,使分页变的单纯。但虽然 DnD 尚处于提案期,各应用程序对其规范化仍未标准化,很多该事件在相同应用程序中会再次出现相同效用。

要采用 DnD,须要明晰三件事,其一须要拖曳的原素,并有可置放拖曳原素的边线。分页不外乎是将原素从两个边线拖至另两个边线。

Drag

具体来说他们须要选定要拖曳的原素,增设方式很单纯,给该 DOM 原素增设 draggable 特性,特性值增设为 true。比如说这种:

<img src=“images/0.jpg”draggable=“true”id=“img0”/>

事实上,以上标识符多此一举了,网页中的图片(img)、链接(带 href 的 a 标签)和文本默认即为可拖曳。为了标准化,最好还是都加上该 draggable 特性为好。

draggable 特性还有两个值,分别是 false 和 auto,顾名思义,false 即增设为不可拖曳,auto 即为应用程序默认值。

当他们左键点选(按下)可拖曳的 DOM 原素,轻轻移动,即触发 ondragstart 该事件,该该事件只会触发一次。通常他们会在 ondragstart 该事件中记录正在被拖曳的原素信息(ondrop 的时候好对其进行处理)。比如说 demo 中记录了正在被拖曳的原素 id:

for(vari = lis.length;i;){

lis[i].ondragstart = function(e){

e.dataTransfer.setData(id,e.target.id);

};

}

ondragstart 该事件触发后,直到分页该事件结束,会一直触发 ondrag 该事件。

Drop

其次他们须要明晰被拖曳原素可置放的边线,ondragover 该事件规定在何处置放被拖曳的数据。

默认地,无法将原素置放到其他原素中,如果须要设置允许置放,他们必须阻止对原素的默认处理形式:

vardus = document.querySelector(.dustbin);

dus.ondragover = function(e){

e.preventDefault();

};

当原素被拖曳到某一原素上时,即会触发后者的 ondrop 该事件,如果须要正确触发 ondrop 该事件,还须要取消一些 DnD 该事件的默认行为:

dus.ondrop = function(e){

// 调用 preventDefault() 来避免应用程序对数据的默认处理(drop 该事件的默认行为是以链接形式打开)

e.preventDefault();

e.stopPropagation();// 兼容ff

varid = e.dataTransfer.getData(id)

,node = document.getElementById(id);

node.parentNode.removeChild(node);

};

很多文献中说要取消 ondragenter() 该事件的默认行为,楼主在实际操作中仍未发现这点。

该事件

上面已经提到了 DnD 中的三个该事件,dragstart、dragover 以及 drop,其实 DnD 还有几个该事件,它们的发生顺序是:

dragstart(drag原素) -> drag(drag原素) -> dragenter(drop原素) -> dragover(drop原素)->dragleave(drop原素) -> drop(drop原素) -> dragend(drag原素)

不难理解,分页该事件开始时触发 ondragstart 该事件,当被拖曳原素进入可置放的原素时,触发 ondragenter 该事件(ondragenter 并不是在两个原素相交时即触发,而是该被拖拽原素在目标原素上移动一段时间后才触发),之后一段该事件会持续触发 ondragover 该事件(可参照 mouseover),当被拖曳原素离开可置放原素的一瞬间,触发 ondragleave(和 ondragenter 对应) 该事件,当松开鼠标并且被拖拽原素正好在可置放原素上时,触发 ondrop 该事件,当分页事件结束时,触发 ondragend(和 ondragstart 对应) 该事件,无论分页操作是否成功,均会触发该该事件。

dataTransfer

拖曳过程中,回调函数接受的该事件参数,有两个 dataTransfer 特性。它指向两个对象,包含了与拖曳相关的各种信息。

dataTransfer 对象主要有两种方法:getData() 和 setData(),须要注意的是,只有在 dragstart 和 drop 该事件中采用这两个方法。不难想象,getData() 可以取得由 setData() 保存的值。setData() 方法的第两个参数,也是 getData() 方法唯一的两个参数,是个字符串,表示保存的数据类型,取值为 ‘text’ 或 ‘URL’。IE 只定义了 ‘text’ 和 ‘URL’ 两种有效的数据类型,而 HTML5 则对此加以扩展,允许选定各种 MIME 类型。

在拖曳文本框中的文本时,应用程序会自动调用 setData() 方法,将拖曳的文本以 ‘text’ 格式保存在 dataTransfer 对象中,类似地,在分页链接或者图像时,会自动调用 setData() 将 URL 信息保存,如果有须要,在 drop 该事件中可以用 getData() 读取应用程序保存的值。

但这似乎并没有什么卵用,他们在实际开发中多数还是对 DOM 的操作,于是多数情况下他们在 dragstart 该事件处理程序中调用 setData(),手工保存自己要传输的数据,接着在 drop 该事件中读取,有点像 jQuery 的 data 该事件。

dropEffect 与 effectAllowed

dropEffect 和 effectAllowed 是前面说的 dataTransfer 对象的两个特性,有啥用?单纯地说,有两个用处,其一可以增设原素被拖拽时的鼠标样式,并有可以增设原素是否可被置放。

这里我测试了三款应用程序,chrome、ff 和 uc,chrome 和 uc 表现相似。

一般他们将原素脱离原来的边线,鼠标手势会变成 “禁手”,直到原素被拖至可置放区域上。

HTML5 — 让拖放变的流行起来

但 ff 不然,在 ff 中,原素在拖曳的过程中不会显示 “禁手”。

当原素被拖至可置放区域上时,默认鼠标手势如下。

HTML5 — 让拖放变的流行起来

其实通过增设 dropEffect 和 effectAllowed 总共能增设三种鼠标手势(move, copy,和 link),分别如下(move 和默认貌似一样):

HTML5 — 让拖放变的流行起来

须要在 ondragstart 方法中增设 effectAllowed,在 ondragover 方法中增设 dropEffect。具体可以参考 demo标识符。

他们也可以对 dropEffect 和 effectAllowed 的值进行设定,让某 drop 原素只能放 move 原素,或者 copy 原素等。具体可以看下这篇,HTML5魔法堂:全面理解Drag & Drop API,讲的很好。取值也可以参照高程 484 页。

总之要知道的是,DnD 并不会帮你完成 copy 或者 move 的任何操作,而是须要用户在 DnD 过程中,记录须要操作的对象信息,接着在 drop 该事件中完成 copy 或者 move 等的操作。

Tricks

还有几个实践过程中发现的问题。

将 Demo 在 ff 中打开,图片拖至空处,会自动在新标签中打开图片,尽管我已经在各种该事件中加上了 preventDefault(),尚不清楚原因。

如果可拖拽原素,初始在两个可置放原素内部,先把原素拖出去,再放回来,将会触发 ondrop 该事件,但 e.target 却是被拖拽的原素。如果置放在其他原素,target 会指向被置放的原素,而不是拖拽原素。这点可以通过判断 target 原素得到解决。关于这点可以看下 w3cschool 的这个 demo,打开控制台,将图片拖出去,再拖回来,控制台会打印出错误,显然标识符没有考虑到而此点。

Read More:

HTML 5 分页

HTML5魔法堂:全面理解Drag & Drop API

HTML5 分页API

HTML5拖放操作API及实例

【今日微信公号推荐↓】

HTML5 — 让拖放变的流行起来HTML5 — 让拖放变的流行起来

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务