《JavaScript高級程序設計》筆記:HTML5腳本編程(16)

跨文檔消息傳遞

跨文檔消息傳遞(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處理程序的事件對象包含如下三方面的重要信息。異步

  • data:做爲postMessage()第一個參數傳入的字符串數據。
  • origin:發送消息的文檔所在的域,例如"http://www.wrox.com"。
  • source:發送消息的文檔的window對象的代理。這個代理對象主要用於在發送上一條消息的窗口中調用postMessage()方法。若是發送消息的窗口來自同一個域,那這個對象就是window。
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

  • (1)dragstart
  • (2)drag
  • (3)dragend

上述三個事件的目標都是被拖動的元素。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對象。

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和effectAllowed

其中,經過dropEffect屬性能夠知道被拖動的元素可以執行哪一種放置行爲。這個屬性有4個可能的值。

  • none:不能把拖動的元素放在這裏。這是除文本框以外全部元素的默認值。
  • move:應該把拖動的元素移動到放置目標。
  • copy:應該把拖動的元素複製到放置目標。
  • link:表示放置目標會打開拖動的元素(但拖動的元素必須是一個連接,有URL)。

要使用dropEffect屬性,必須在ondragenter事件處理程序中針對放置目標來設置它。

dropEffect屬性只有搭配effectAllowed屬性纔有用。effectAllowed屬性表示容許拖動元素的哪一種dropEffect。effectAllowed屬性有如下可能的值:

  • 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事件處理程序中設置effectAllowed屬性。

可拖動

默認狀況下,圖像、連接、文本是能夠拖動的,文本只有在被選中的狀況下才能拖動,而圖像和連接在任什麼時候候均可以拖動。

讓其它元素能夠拖動,HTML5爲全部的HTML元素規定了一個draggable屬性。

<!--讓圖像不可拖動-->
<img src="images/avatar.png" draggable="false"/>

<!--讓這個元素能夠拖動-->
<div draggable="true">可拖動的元素</div>

其它成員

 HTML5規範規定dataTransfer對象還有下列屬性和方法:

  • addElement(element):爲拖動操做添加一個元素。添加這個元素隻影響數據(即增長做爲拖動源而響應回調的對象),不會影響拖動操做時頁面元素的外觀。
  • clearData(format):清除以特定格式保存的數據。
  • setDragImage(element,x,y):指定一副圖像,當拖動發生時,顯示在光標下方。這個方法接收的三個參數分別爲要顯示的HTML元素和光標在圖像中的x、y座標。其中,HTML元素能夠是一副圖像,也能夠是其它元素。
  • types:當前保存的數據類型。這是一個相似數組的集合,以「text」這樣的字符串形式保存着數據類型。

 媒體元素

<audio>和<video>

相關文章
相關標籤/搜索