版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/qq1010885678/article/details/38090663
在html中普通的父容器調用子容器中的方法十分簡單
因為這兩個容器的所有方法和屬性都在同一個dom模型中
可以直接控制和使用
但是如果子容器中是一個iframe标簽又是怎樣的情況?
iframe請求另外一個頁面并顯示
這時候父子容器的方法和屬性等都不在一個dom模型中了
有些情況又要求父子容器能夠互相調用方法來實作某一功能
這時候要怎麼實作這個要求呢
其實一個html頁面内的所有方法等最後都會被加載到該頁面dom模型的window内
例如經常使用的
window.onload()//在頁面加載完成後執行的事件/方法
如果在一個頁面内定義了一個js方法
function DoSomething(){...}
那麼這個方法最後會被加載到window下面
可以通過這個window點出來并使用這個方法
那麼,現在隻要能夠拿到子容器iframe内部頁面的window就可以在父容器中調用子容器的方法了
例子:
HtmlPage1.html頁面中
<input type="button" id="btnShowChild" value="點選彈出子容器"/>
<div id="divChild">
<iframe id="ifmChild" src="javascript:void(0)"></iframe>
</div>
頁面如下:
很簡單就一個按鈕的頁面
點選這按鈕,彈出id為divChild的div
在這個div中包含一個iframe
在點選按鈕彈出div的同時設定iframe的src屬性為HtmlPage2.html
為了友善操作使用到了jquery easyui的插件
在該頁面中輸入以下js代碼:
//在窗體加載完成後
$(function () {
//獲得div
var divChild = $("#divChild");
//剛開始的時候設定div隐藏
divChild.css("display", "none");
//按鈕點選事件
$("#btnShowChild").click(function () {
//設定iframe的src屬性為HtmlPage2.html
$("#ifmChild").attr("src", "HtmlPage2.html");
//顯示div
divChild.css("display", "block");
//将div以對話框的形式彈出(easyui)
divChild.dialog({
title: "我是父容器",
buttons: [{
//确認按鈕
text: '送出子容器中的表單',
iconCls: "icon-ok",
handler: function () {
//點選該按鈕之後執行的方法
}
}, {
//關閉按鈕
text: '關閉',
handler: function () {
$("#divChild").dialog('close');
}
}]
});
});
});
HtmlPage2.html頁面:
<form id="fmSubmit">
<table>
<tr>
<td colspan="2">
我其實是一個Iframe标簽,是一個子容器
</td>
</tr>
<tr>
<td>
使用者名:
</td>
<td>
<input type="text" id="txtUid" name="txtUid"/>
</td>
</tr>
<tr>
<td>
密碼:
</td>
<td>
<input type="password" id="txtPwd" name="txtPwd"/>
</td>
</tr>
</table>
</form>
一個表單包含一個table的簡單布局
現在回到HtmlPage1.html頁面
點選頁面上的按鈕:
這時候已經将HtmlPage2.html頁面通過一個iframe标簽以子容器的形式顯示在HtmlPage1.html頁面中
這時我們需要的效果是
點選“送出子容器中的表單”按鈕
使HtmlPage2.html中的表單異步送出
成功送出之後再HtmlPage1.html中關閉這個子容器,并将HtmlPage1.html頁面上的按鈕值顯示為“完成”
首先要通過點選父容器中的一個按鈕來執行子容器中的一個方法使表單送出
可以通過獲得子容器的window來得到并執行這個方法
是以在HtmlPage2.html中定義這樣一個js方法:
//送出表單方法
function SubmitForm() {
//獲得頁面文本框的值
var txtUid = $("#txtUid").val();
var txtPwd = $("#txtPwd").val();
//通過jquery異步送出表單
$.ajax({
url: "Handler1.ashx",
data: "Uid=" + txtUid + "&&Pwd=" + txtPwd,
type: "Get",
success: function(res) {
if (res == "ok") {
//送出成功之後執行的方法
} else {
alert("子容器iframe異步送出出錯!");
}
}
});
}
通過一個一般處理程式來接收資料并簡單的判斷然後傳回資料
context.Response.ContentType = "text/plain";
if (context.Request.QueryString["Uid"] == "111" && context.Request.QueryString["Pwd"] == "111")
{
context.Response.Write("ok");
}
else
{
context.Response.Write("error");
}
此時在HtmlPage1.html并不知道怎麼來獲得子容器的window
但是可以知道ifram标簽肯定是重要的目标,因為是它在承載顯示另外一個頁面
是以可以在頁面1中的“送出子容器中的表單”按鈕事件先獲得這個iframe标簽,然後觀察它的屬性
divChild.dialog({
title: "我是父容器",
buttons: [{
//确認按鈕
text: '送出子容器中的表單',
iconCls: "icon-ok",
handler: function () {
//點選該按鈕之後執行的方法
//獲得子容器的iframe标簽
var ifmChild = $("#ifmChild");
}
}, {
//關閉按鈕
text: '關閉',
handler: function () {
$("#divChild").dialog('close');
}
}]
});
在浏覽器中打開頁面1,并進行調試
點選“彈出子容器”按鈕
并點選對話框中的“送出子容器中的表單”按鈕,命中斷點,将ifmChild添加監視檢視
可以看到,這個ifame标簽似乎是一個數組,而且隻有一個元素
那麼打開這唯一一個元素看看裡面有沒有window屬性
但是找了全部找了一遍好像沒有發現window這個屬性
但是卻找到了一個contentWindow,它在這裡
可以看到這個contentWindow後面還跟着一個[object Window]
先不管這是啥意思
反正跟window有關先拿來用看看
還是修改對話框中按鈕的事件
divChild.dialog({
title: "我是父容器",
buttons: [{
//确認按鈕
text: '送出子容器中的表單',
iconCls: "icon-ok",
handler: function () {
//點選該按鈕之後執行的方法
//獲得子容器的iframe标簽
//var ifmChild = $("#ifmChild");
var childWindow = $("#ifmChild")[0].contentWindow;
childWindow.SubmitForm();
}
}, {
//關閉按鈕
text: '關閉',
handler: function () {
$("#divChild").dialog('close');
}
}]
});
其實到這裡很明了了,如果有裝R#插件的同學可以甚至直接在childWindow點出子容器中的SubmitForm方法
然後轉到頁面2
在表單送出成功後的事件中
獲得目前window的parent屬性
這個屬性就是頁面1的window,因為頁面1就是頁面2的父容器
如此一來,就可以再頁面2中直接使用父容器頁面1中的方法了
//通過jquery異步送出表單
$.ajax({
url: "Handler1.ashx",
data: "Uid=" + txtUid + "&&Pwd=" + txtPwd,
type: "Get",
success: function(res) {
if (res == "ok") {
//送出成功之後執行的方法
window.parent.AfterChildSubmit();
} else {
alert("子容器iframe異步送出出錯!");
}
}
});
是以要在頁面1中準備一個AfterChildSubmit方法
function AfterChildSubmit() {
//關閉對話框
$("#divChild").dialog('close');
//消息提示
alert("子容器成功調用父容器的AfterChildSubmit方法");
//修改按鈕的值
$("#btnShowChild").val("完成");
}
最後測試如下: