客戶端與服務(wù)器傳值還有幾個(gè)經(jīng)常會遇到的問題
1.頁面和其打開的新窗口的數(shù)據(jù)傳遞
2.多窗口之間消息傳遞
3.頁面與嵌套的iframe消息傳遞
4.上面三個(gè)問題的跨域數(shù)據(jù)傳遞
1.postMessage()
這些問題都有一些解決辦法,但html5引入的message的API可以更方便、有效、安全的解決這些難題。postMessage()方法允許來自不同源的腳本采用異步方式進(jìn)行有限的通信,可以實(shí)現(xiàn)跨文本檔、多窗口、跨域消息傳遞。
postMessage(data,origin)方法接受兩個(gè)參數(shù)
1.
data:要傳遞的數(shù)據(jù),html5規(guī)范中提到該參數(shù)可以是JavaScript的任意基本類型或可復(fù)制的對象,然而并不是所有瀏覽器都做到了這點(diǎn)兒,部分瀏覽器只能處理字符串參數(shù),所以我們在傳遞參數(shù)的時(shí)候需要使用JSON.stringify()方法對對象參數(shù)序列化,在低版本IE中引用json2.js可以實(shí)現(xiàn)類似效果。
2.origin:字符串參數(shù),指明目標(biāo)窗口的源,協(xié)議+主機(jī)+端口號[+URL],URL會被忽略,所以可以不寫,這個(gè)參數(shù)是為了安全考慮,postMessage()方法只會將message傳遞給指定窗口,當(dāng)然如果愿意也可以建參數(shù)設(shè)置為"*",這樣可以傳遞給任意窗口,如果要指定和當(dāng)前窗口同源的話設(shè)置為"/"。
2.iframe
兩個(gè)基本概念:
主頁面指的是嵌套iframe的頁面
子頁面指的是被嵌套的iframe頁面
2.1 在主頁面,想要操作子頁面的DOM元素
contentWindow 兼容各個(gè)瀏覽器,可取得子窗口的 window 對象。
contentDocument Firefox 支持,> ie8 的ie支持,可取得子窗口的 document 對象。
var ifr = document.getElementById("iframe"); // 先獲取iframe對象,此時(shí)的window是主頁面的window對象
ifr.contentWindow.document.getElementById("div1") //獲取子頁面iframe的window對象,此時(shí)ifr.contentWindow返回的是iframe的window對象,后面可以繼續(xù)調(diào)用document方法
<iframe src="test.html" id=""></iframe> // 獲取要操作的子頁面的DOM元素
2.2 兼容獲取document對象:
var getIFrameDoc = function(){
var ifr = document.createElement("iframe");
document.getElementsByTagName("body")[0].appendChild(ifr);
return ifr.contentDocument || ifr.contentWindow.document;
}
2.3 在子頁面,要操作主頁面的DOM元素
window.parent 在iframe頁面通過parent可以獲得主頁面的window,接著就可以正常訪問父親頁面的元素了;
window.top() 這里的top是獲取頂層的window,當(dāng)有多層iframe嵌套的時(shí)候使用
var ifr = document.getElementByTagName("iframe");
ifr.parent.document.getElementById("div1")
<iframe src="test.html" id=""></iframe>
3.一些基本使用:
1,
document.getElementById("myiframe").contentWindow得到iframe對象后,就可以通過contentWindow得到iframe包含頁面的window對象,然后就可以正常訪問頁面元素了;
2,$("#myiframe")[0].contentWindowjquery選擇器獲得iframe,先把jquery對象轉(zhuǎn)換為DOM對象,或者使用get()方法轉(zhuǎn)換;
3,$("#myiframe")[0].contentWindow.$("#div1").val()可以在得到iframe的window對象后接著使用jquery選擇器進(jìn)行頁面操作;
4,$("#myiframe")[0].contentWindow.username="starry";可以通過這種方式向iframe頁面?zhèn)鬟f參數(shù),在iframe頁面window.username就可以獲取到值,username是自定義的全局變量;
5,在iframe頁面通過parent可以獲得主頁面的window,接著就可以正常訪問父親頁面的元素了;
6,parent.$("#frameA")[0].contentWindow.document.getElmentById("#frameB");同級iframe頁面之間調(diào)用,需要先得到父親的window,然后調(diào)用同級的iframe得到window進(jìn)行操作;