跨文檔消息傳遞(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>