Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML5拖拽笔记之二 #32

Open
cy0707 opened this issue Dec 30, 2016 · 0 comments
Open

HTML5拖拽笔记之二 #32

cy0707 opened this issue Dec 30, 2016 · 0 comments

Comments

@cy0707
Copy link
Owner

cy0707 commented Dec 30, 2016

拖拽事件

事件 描述
dragstart 事件主体是被拖放元素,在开始拖放被拖放元素时触发,即开始的拖放的那一瞬间。
drag 事件主体是被拖放元素,在正在拖放被拖放元素时触发,从拖放开始直到拖放进行目标元素中。
dragend 事件主体是被拖放元素,在整个拖放操作结束时触发,即进入新目标元素的那一瞬间。
dragenter 事件主体是目标元素,在被拖放元素进入某元素时触发,即新进入的目标元素。
dragover 事件主体是目标元素,在被拖放在某元素内移动时触发
dragleave 事件主体是目标元素,在被拖放元素移出目标元素是触发,离开的上一个目标元素。
drop 事件主体是目标元素,在被拖拽的元素在目标元素上同时鼠标放开触发,新进入的目标元素。

为了减少事件,你可以在事件 ondragenter 的时候 绑定方法 ,而 ondragleave 的时候,删除 方法。最好不要绑定在 dragover 上,它就像 mouseover ,在拖动的过程中不断触发,对于浏览器的负担就很大了,浏览器还有可能崩溃。

成为目标元素

把任何元素变成有效的放置目标,其方法是重写dragover事件的默认行为。例如:假如你有一个ID为‘droptarget’的div元素,可以用如下代码把它变成一个放置目标。

var droptarget = document.getElementById('droptarget');
droptarget,ondragover = function(e){
    e.preventDefault();
}

在ondragover中一定要执行preventDefault(),否则ondrop事件不会被触发。另外,如果是从其他应用软件或是文件中拖东西进来,尤其是图片的时候,默认的动作是显示这个图片或是相关信息,并不是真的执行drop。此时需要用document的ondragover事件把它直接干掉。

dataTransfer对象

只有简单的拖放而没有数据变化是没有什么用的。为了在拖放操作时实现数据交换HTML5定义了dataTransfer对象来传递拖拽的数据。

因为它是事件对象的属性,所以只能在拖放事件的事件处理程序中访问dataTransfer对象。在事件处理程序中,可以使用这个对象的属性和方法来 完善拖放功能。

<div id="draggable" draggable="true" ondragstart="event.dataTransfer.setData('text/plain',null)">
           This div is draggable
</div>

getData()和setData()

ataTransfer对象有 getData()和setData()两个主要方法,操作dataTransfer中携带的数据。不难想象,getData()可以取得由setData()保存的值。setData()方法的第一个参数,也是getDAta()方法唯一的一个参数,表示保存的数据类型。

IE只定义了“text”和“URL”两种有效的数据类型,而HTML5则对此加以扩展,允许指定各种MIME类型。考虑到向后兼容,HTML5也支持“text”和“URL”,但这两种类型会被映射为“text/plain”和“text/uri-list”。如下所示:

  • text/html:文本文字格式
  • text/plain:HTML代码格式
  • text/xml:XML字符格式
  • text/url-list:URL格式列表

保存在dataTransfer对象中的数据只能在drop事件处理程序中读取。如果在ondrop处理程序中没有读到数据,那就是dataTransfer对象已经被销毁,数据也丢失了。

在拖动文本框中的文本时,浏览器会调用setData()方法,将拖动的文本以“text”格式保存在dataTransfer对象中。类似地,在拖放链接或图像时,会调用setData()方法并保存URL。然后,在这些元素被拖放到放置目标时,就可以通过getData()读到这些数据。

当然,作为开发人员,你也可以在dragstart事件处理程序中调用setData(),手工保存自己要传输的数据,以便将来使用。

将数据保存为文本和保存为URL是有区别的。如果将数据保存为文本格式,那么数据不会得到任何特殊处理。而如果将数据保存为URL,浏览器会将其当成网页中的链接。换句话说,如果你把它放置到另一个浏览器窗口中,浏览器就会打开该URL。

Firefox在其第5个版本之前不能正确地将“URL”和“text”映射为“text/uri-list”和“text/plain”。但是却能把“Text”映射为“text/plain”。为了更好地在跨浏览器的情况下从dataTransfer对象取得数据,最好在取得URL数据时检测两个值,而在取得文本数据时使用“text”。

var dataTransfer = event.dataTransfer;
//读取URL
var url = dataTransfer.getData("url") || dataTransfer.getData("text/uri-list");
//读取文本
var text = dataTransfer.getData("Text");

注意:一定要把短数据类型放在前面,因为IE 10及之前的版本仍然不支持扩展的MIME类型名,而它们在遇到无法识别的数据类型时,会抛出错误。

dropEffect属性

dropEffect属性只有搭配effectAllowed属性才有用。effectAllowed属性表示允许拖放元素的哪种dropEffect,effectAllowed属性可能的值如下。

  • uninitialized:没有该被拖动元素放置行为。
  • none:被拖动的元素不能有任何行为。
  • copy:只允许值为“copy”的dropEffect。
  • link:只允许值为“link”的dropEffect。
  • move:只允许值为“move”的dropEffect。
  • copyLink:允许值为“copy”和“link”的dropEffect。
  • copyMove:允许值为“copy”和”link”的dropEffect。
  • linkMove:允许职位“link”和”move”的dropEffect。
  • all:允许任意dropEffect。

必须在ondraggstart事件处理程序中设置effectAllowed属性。

假设你想允许用户把文本框中的文本拖放到一个

元素中。首先,必须将dropEffect和effectAllowed设置为”move”。但是,由于
元素的放置事件的默认行为是什么也不做,所以文本不可能自动移动。重写这个默认行为,就能从文本框中移走文本。然后你就可以自己编写代码将文本插入到
中,这样整个拖放操作就完成了。如果将dropEffect和effectAllowed的值设置为”copy”,那就不会自动移走文本框中的文本。

兼容性

支持draggable属性的浏览器有IE10+、Firefox 4+、Safari 5+和Chrome。Opera 11.5以及之前的版本都不支持HTML5的拖放功能。另外,为了让Firefox 支持可拖动属性,还必须在dataTransfer对象中保存了一些信息。

在firefox下拖动出现新窗口的解决办法

发现在firefox下拖放,会出现新的tab 页签,即使在ondragover、ondrop中使用了event.preventDefault也无济于事,在mozllia上MDN的例子拖动也会弹出新的tab 页签。

####解决方法

dataTransfer.setData("asdf","")把这个第一个参数不设置提供的那些类型,设置其它的就可以,再设置为提供的那些类型,就会弹出新窗口。

参考文章

HTML Drag and Drop API
HTML 5的革新—— drag && drop(拖动)
html drag api 在firefox 下 拖动出现新窗口的解决办法

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant