除非数据受影响,否则简单的拖放并没有实际意义。为实现拖动操作中的数据传输,IE5 在 event 对象上暴露了 dataTransfer 对象,用于从被拖动元素向放置目标传递字符串数据。因为这个对象是 event 的属性,所以在拖放事件的事件处理程序外部无法访问 dataTransfer。在事件处理程序内部,可以使用这个对象的属性和方法实现拖放功能。dataTransfer 对象现在已经纳入了 HTML5 工作草案。 15 dataTransfer 对象有两个主要方法:getData()和 setData()。顾名思义,getData()用于获
取 setData()存储的值。setData()的第一个参数以及 getData()的唯一参数是一个字符串,表示要
设置的数据类型:"text"或"URL",如下所示:
// 传递文本
event.dataTransfer.setData("text", "some text"); let text = event.dataTransfer.getData("text");
// 传递URL
event.dataTransfer.setData("URL", "http://www.wrox.com/"); let url = event.dataTransfer.getData("URL");
虽然这两种数据类型是 IE 最初引入的,但 HTML5 已经将其扩展为允许任何 MIME 类型。为向后 兼容,HTML5 还会继续支持"text"和"URL",但它们会分别被映射到"text/plain"和"text/uri-list"。
dataTransfer 对象实际上可以包含每种 MIME 类型的一个值,也就是说可以同时保存文本和 URL,两者不会相互覆盖。存储在 dataTransfer 对象中的数据只能在放置事件中读取。如果没有在 ondrop 事件处理程序中取得这些数据,dataTransfer 对象就会被销毁,数据也会丢失。
在从文本框拖动文本时,浏览器会调用 setData()并将拖动的文本以"text"格式存储起来。类似 地,在拖动链接或图片时,浏览器会调用 setData()并把 URL 存储起来。当数据被放置在目标上时, 可以使用 getData()获取这些数据。当然,可以在 dragstart 事件中手动调用 setData()存储自定 义数据,以便将来使用。
作为文本的数据和作为 URL 的数据有一个区别。当把数据作为文本存储时,数据不会被特殊对待。 而当把数据作为 URL 存储时,数据会被作为网页中的一个链接,意味着如果把它放到另一个浏览器窗 口,浏览器会导航到该 URL。
原生拖放 633
直到版本 5,Firefox 都不能正确地把"url"映射为"text/uri-list"或把"text"映射为"text/plain"。 不过,它可以把"Text"(第一个字母大写)正确映射为"text/plain"。在通过 dataTransfer 获取 数据时,为保持最大兼容性,需要对 URL 检测两个值并对文本使用"Text":
// 读取文本 24
let dataTransfer = event.dataTransfer;
// 读取URL
let url = dataTransfer.getData("url") || dataTransfer.getData("text/uri-list");
let text = dataTransfer.getData("Text");
这里要注意,首先应该尝试短数据名。这是因为直到版本 10,IE 都不支持扩展的类型名,而且会 在遇到无法识别的类型名时抛出错误。 25
dropEffect与effectAllowed
dataTransfer 对象不仅可以用于实现简单的数据传输,还可以用于确定能够对被拖动元素和放置 目标执行什么操作。为此,可以使用两个属性:dropEffect 与 effectAllowed。
dropEffect 属性可以告诉浏览器允许哪种放置行为。这个属性有以下 4 种可能的值。 “none”:被拖动元素不能放到这里。这是除文本框之外所有元素的默认值。
“move”:被拖动元素应该移动到放置目标。
“copy”:被拖动元素应该复制到放置目标。
“link”:表示放置目标会导航到被拖动元素(仅在它是 URL 的情况下)。
在把元素拖动到放置目标上时,上述每种值都会导致显示一种不同的光标。不过,是否导致光标示 意的动作还要取决于开发者。换句话说,如果没有代码参与,则没有什么会自动移动、复制或链接。唯 一不用考虑的就是光标自己会变。为了使用 dropEffect 属性,必须在放置目标的 ondragenter 事件 处理程序中设置它。
除非同时设置 effectAllowed,否则 dropEffect 属性也没有用。effectAllowed 属性表示对 被拖动元素是否允许 dropEffect。这个属性有如下几个可能的值。
“uninitialized”:没有给被拖动元素设置动作。 “none”:被拖动元素上没有允许的操作。
“copy”:只允许"copy"这种 dropEffect。
“link”:只允许"link"这种 dropEffect。
“move”:只允许"move"这种 dropEffect。
“copyLink”:允许"copy"和"link"两种 dropEffect。
“copyMove”:允许"copy"和"move"两种 dropEffect。
“linkMove”:允许"link"和"move"两种 dropEffect。
“all”:允许所有 dropEffect。
必须在 ondragstart 事件处理程序中设置这个属性。 假设我们想允许用户把文本从一个文本框拖动到一个