跨文档消息传递(cross-document messaging),有时候简称为XDM,指的是在来自不一样域的页面间传递消息。例如,www.wrox.com域中的页面与位于一个内嵌框架中的p2p.wrox.com域中的页面通讯。数组
XDM的核心是postMessage()方法。在HTML5规范中,除了XDM部分以外的其余部分也会提到这个方法名,但都是为了同一个目的:向另外一个地方传递数据。对于XDM而言,“另外一个地方”指的是包含在当前页面中的<iframe>元素,或者由当前页面弹出的窗口。浏览器
postMessage()方法接收两个参数:一条消息和一个表示消息接收方来自哪一个域的字符串。第二个参数对保障安全通讯很是重要,能够防止浏览器把消息发送到不安全的地方。安全
//注意全部支持XDM的浏览器也支持iframe的contentWindow属性 var iframeWindow = document.getElementById("myframe").contentWindow; iframeWindow.postMessage("A secret","http://www.wrox.com");
最后一行代码尝试向内嵌框架中发送一条消息,并指定框架中的文档必须来源于http:www.wrox.com域。若是来源匹配,消息会传递到内嵌框架中;不然,postMessage()什么也不作。若是传给postMessage()的第二个参数是“*”,则表示能够把消息发送给来自任何域的文档,但咱们不推荐这样作。框架
接收到XDM消息时,会触发window对象的message事件。这个事件是以异步形式触发的,所以,从发送消息到接收消息(触发接收窗口的message事件)可能要通过一段时间的延迟。触发message事件后,传递给onmessage处理程序的事件对象包含如下三方面的重要信息。异步
window.addEventListener("message",function(event){ if(event.origin == 'http://www.wrox.com'){ //处理接收到的数据 processMessage(event.data); //可选:向来源窗口发送回执 event.source.postMessage("Received!","http://p2p.wrox.com"); } },false);
XDM还有一些怪异之处。postMessage()的第一个参数最先是做为“永远都是字符串来实现的”,但后来改变了可使用任意结构了。并不是全部浏览器都支持任意结构,因此最好仍是传入字符串,即在要传递数据以前调用JSON.stringify()方法,而后在onmessage事件处理程序中调用JSON.parse()。ide
拖动某元素时,将依次触发下列事件:post
上述三个事件的目标都是被拖动的元素。url
当某个元素被拖动到一个有效的放置目标上时,下列事件会依次执行:spa
(1)dragenter代理
(2)dragover
(2)dragleave或drop
只要有元素被拖动到放置目标上,就会触发dragenter事件(相似于mouseover事件)。紧随其后的是dragover事件,并且在被拖动的元素还在放置目标的范围内移动时,就会持续触发该事件。若是元素被拖出了放置目标,dragover事件就再也不发生,但会触发dragleave事件(相似于mouseout事件)。若是元素被放到了放置目标中,则会触发drop事件而不是dragleave事件。上述三个事件的目标都是做为放置目标的元素。
在拖动元素通过某些无效放置目标时,能够看到一种特殊的光标(圆环中有一条反斜线),表示不能放置。虽然全部元素都支持放置目标事件,但这些元素默认是不容许放置的。若是拖动元素通过不容许放置的元素,不管用户若是操做,都不会发生drop事件。不过,你能够把任何元素变成有效的放置目标,方法是重写dragenter和dragover事件的默认行为。例如,假设有一个ID为“droptarget”的<div>元素,能够用以下代码将它变成一个放置目标。
var droptarget = document.getElementById("droptarget"); EventUtil.addHandler(droptarget,"dragover",function(){ EventUtil.preventDefault(event); }); EventUtil.addHandler(droptarget,"dragenter",function(){ EventUtil.preventDefault(event);
以上代码执行后,你就会发现当拖动着元素移动到放置目标上时,光标变成了容许放置的符号。固然,释放鼠标也会触发drop事件。
在Firefox3.5中,放置事件的默认行为是打开被放到放置目标上的URL。换句话说,若是是把图像拖动到放置目标上,页面就会转向图像文件;而若是是把文本拖放到放置目标上,则会致使无效URL错误。所以,为了让Firefox支持正常的拖放,还要取消drop事件的默认行为,阻止它打开URL:
EventUtil.addHandler(droptarget,"drop",function(){ EventUtil.preventDefault(event); });
dataTransfer对象是事件对象的一个属性,用于从被拖动元素向放置目标传递字符串格式的数据。由于他是事件对象的属性,因此只能在拖动事件的事件处理程序中访问dataTransfer对象。
dataTransfer对象有两个主要的方法:getData()和setData()。getData()能够取得由setData()保存的值。setData()方法的第一个参数,也是getData()方法惟一的一个参数,是一个字符串,表示保存的数据类型,取值为“text”或“URL”,以下代码:
//设置和接收文本数据 event.dataTransfer.setData("text","some text"); var text = event.dataTransfer.getData("text"); //设置和接收url event.dataTransfer.setData("URL","http://www.wrox.com/"); var url = event.dataTransfer.getData("URL");
IE只定义了“text”和“URL”两种有效的数据类型,而HTML5则对此加以扩展,容许指定各类MIME类型。考虑到向后兼容,HTML5也支持“text”和“URL”,但这两种类型会被映射为“text/plain”和“text/url-list”。
实际上,dataTransfer对象能够为每种MIME类型都保存一个值。换句话说,同时在这个对象中保存一段文本和一个URL不会有任何问题。不过,保存在dataTransfer对象的数据只能在drop事件处理程序中读取。若是在ondrop处理程序中没有读到数据,那就是dataTransfer对象已经被被销毁了,数据也丢失了。
Firfox在其第五个版本以前不能将"URL"和“text”映射为“text/url-list”和“text/plain”,但却能把“Text”映射为“text/plain”,为了更好的兼容浏览器,可以使用以下代码:
var dataTransfer = event.dataTransfer; //读取URL var url = dataTransfer.getData('url') || dataTransfer.getData("text/url-list"); //读取文本 var text = dataTransfer.getData("Text");
注意:必定要把短数据类型放到前面,由于IE10以及以前的版本不支持扩展的MIME类型,而他们在遇到没法识别的数据类型时,会抛出错误。
其中,经过dropEffect属性能够知道被拖动的元素可以执行哪一种放置行为。这个属性有4个可能的值。
要使用dropEffect属性,必须在ondragenter事件处理程序中针对放置目标来设置它。
dropEffect属性只有搭配effectAllowed属性才有用。effectAllowed属性表示容许拖动元素的哪一种dropEffect。effectAllowed属性有如下可能的值:
必须在ondragstart事件处理程序中设置effectAllowed属性。
默认状况下,图像、连接、文本是能够拖动的,文本只有在被选中的状况下才能拖动,而图像和连接在任什么时候候均可以拖动。
让其它元素能够拖动,HTML5为全部的HTML元素规定了一个draggable属性。
<!--让图像不可拖动--> <img src="images/avatar.png" draggable="false"/> <!--让这个元素能够拖动--> <div draggable="true">可拖动的元素</div>
HTML5规范规定dataTransfer对象还有下列属性和方法:
<audio>和<video>