工作遇到一個bug,彈窗調整至頂層window.top.dialog,使用的artDialog彈窗插件,本來用的好好的,可是隨着需求的增加,bug就出現。
需求:在一個彈窗基礎上,再添加彈窗展示某項數據,後臺接口請求數據
代碼現狀:那個彈窗是通過iframe引用一個新的頁面展示,我要在那個iframe引用的頁面添加另外彈窗
問題:1.那個彈窗若是保證正常展示,那個彈窗展示也是在iframe框架內部,很小,跟要求的全屏遮罩展示有差距
2.拋開上面美觀,降低需求標準貌似也行得通,畢竟功能達標,但是另外一個新需求徹底打破:三層彈窗,就是在第二層彈窗基礎上再次開第三個彈窗
3.既然繞不開,那就使用頂層彈窗window.top,問題隨之而來,iframe內部的dom元素找不到,html控件操作失效,只剩下事件
4.引用的那個頁面是新頁面,但在同個主域名下
問題原因:js的操作dom元素的api都是基於document文檔,iframe內部也遵循這個原理。現在認爲置頂彈窗,突破iframe限制,導致正常api找不到dom元素
問題解決:1.改變查詢範圍,也就是作用域。js和那些插件,例如jQuery等默認都是document範圍查找。
同域下:
使用 window.top或者window.parent.parent獲取瀏覽器最頂層window對象的引用。
可以使用:window.parent.parent.document最頂層元素的DOM對象
window.parent.parent.document.getElementsByTagName("html")來獲取父頁面的HTML元素。
jQuery寫法:
$('xxx',window.parent.document)
主要問題解決了,不過項目中的彈窗需要用到一些事件,radio單選框,input文本輸入框。由於跨域,爲單選框加上class類不起作用,input文本框的value值也獲取不到。可能是我以前沒遇到過此類問題,沒有經驗。我的辦法是,重新綁定事件,重新爲radio綁定onclick事件(重新插入class類樣式),爲input文本框綁定onchange(直接返回value)
jquery寫法:
單選框:重新書寫點擊事件的樣式
<span><input type="radio" name="radio1"/></span>
<span><input type="radio" name="radio1"/></span>
<span><input type="radio" name="radio1"/></span>
$(window.parent.document).on('click','input[type="radio"]',function(){
$(this).parent().addClass('checked');
$(this).parent().siblings().removeClass('checked');
})
文本框:
value值獲取不到,所以需要change事件獲取
<input type="text" placeholder="請輸入xxx" />
$(window.parent.document).on('change','input[type="text"]',function(){
var value = this.value;
})
事情到了這裏,我門還必須注意問題,iframe加載是否完畢,所以我們還需要監聽iframe加載事件。
要確保在iframe加載完成後再進行操作,如果iframe還未加載完成就開始調用裏面的方法或變量,會產生錯誤。判斷iframe是否加載完成有兩種方法:
1. iframe上用onload事件
2. 用document.readyState=="complete"來判斷
由於用到彈窗(artDialog插件),當我們使用window.top.dialog時候,如果有多重彈窗,那麼有可能會造成衝突,導致確定按鈕無法關閉。公司項目就無法自動關閉,我在這裏使用了手動關閉。
//手動關閉dialog
//自定義dialog的id
var dialog1 = art.dialog({
title: '歡迎',
content: '歡迎使用artDialog對話框組件!',
icon: 'succeed',
follow: document.getElementById('btn2'),
ok: function(){
window.top.dialog1.close();//確定按鈕無法自動關閉彈窗時候,這個方法就能夠解決問題
return false;
}
});
以上算是對項目bug的一點筆記,關於iframe跨域種種,具體的可以看下面參考鏈接,講的挺不錯。
參考網址: http://www.jb51.net/article/49809.htm
http://www.cnblogs.com/duankaige/archive/2012/09/20/2695012.html
http://blog.csdn.net/j_y_x_8/article/details/50907366