菜鳥解決“子頁面關閉刷新父頁面局部”問題的歷程


引子

      昨天晚上做一個項目,遇到的一個問題,這個項目是一個在線考試系統,新建一份試卷的頁面,要添加一些試題策略。點擊添加試題策略,彈出添加策略的頁面,策略編輯好之后提交,添加策略頁關閉,當前添加試題頁面策略列表刷新。那么就遇到一個問題,在“添加試卷頁”中點擊“添加策略”按鈕彈出添加策略頁,添加策略后,父頁面只能局部刷新(整體刷新會丟掉頁面輸入框未保存的數據)。

      綜上總結,濃縮成一句話啊,就是“父頁面打開子頁面,子頁面完成操作后觸發父頁面的事件。”

過程

      我在百度和必應里面搜一下,很多解決方案是用window.showModalDialog來實現的,因為它有返回值,可以根據返回值來實現。但是chrome37以后就不支持window.showModalDialog,考慮兼容性,就不能使用window.showModalDialog。所以說,只能用window.open打開,但是window.open沒有返回值,所以只能在子頁面中想辦法觸發父頁面的事件。

      當時第一反應想到的就是,在父頁面寫一個公用事件,讓子頁面調用,很傻的一個想法,這想法實在太不靠譜了(但是我覺得程序員還是要敢於想象),因為每個頁面都是一個對象實例,你調用公用方法,都不知道是在作用那個頁面,其次,被直接調用的必須是靜態方法,靜態方法又是不能對頁面控件做直接操作的,如果不是靜態方法,就需要new一個頁面,完全沒有意義。

      接着想着從C#中來獲取父頁面,從而觸發父頁面的事件,找了一個發現,C#並沒有好的方法能獲取到父頁面。那么就只能從js入手,我對js不是太了解,菜鳥都算不上的菜鳥,我的想法就是用js找到父頁面(js在找父頁面還是很方便的)。搜了一下,有下面幾種方法:

      window.opener.document在頁面運行結果如下:

技術分享

      window.parent.document在頁面運行結果如下:
技術分享

            發現:

window.opener.document獲取的是父級頁面。

window.parent.document獲得的是本身,很奇怪了。

之后查閱了一些資料得出結論:

window.parent能獲取一個框架的父窗口或父框架。頂層窗口的parent引用的是它本身。
window.opener引用的是window.open打開的頁面的父頁面。
opener即誰打開我的,比如A頁面利用window.open彈出了B頁面窗口,那么A頁面所在窗口就是B頁面的opener,在B頁面通過opener對象可以訪問A頁面。 
parent表示父窗口,比如一個A頁面利用iframe或frame調用B頁面,那么A頁面所在窗口就是B頁面的parent。

 

之后,就很順利了的使用“window.opener.document.getElementById(‘Button1‘).click(); ”觸發頁面事件(我實現的是通過一個按鈕來實現這個事件)。我們可以把這個按鈕隱藏起來。

 技術分享

經過以上種種實驗和思考,終於實現了通過子頁面js觸發父頁面某個按鈕的單擊事件,實現子頁面刷新父頁面局部數據的方法。

結果

截圖如下:

打開父頁面,在文本框中隨便輸入一些內容(便於測試是不是僅僅刷新了局部)。

技術分享

點擊打開子頁面:

 技術分享

點擊刷新父級頁局部

 

 技術分享

可以看出,父頁面僅僅局部被刷新了。

技術分享
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>父級頁</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <label runat="server" id="label1" style="color:blue">
            原始標記</label>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <input type="button" value="打開子頁面" onclick="window.open(‘WebForm2.aspx‘)" />
        <div style="display: none">
            <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
        </div>
    </div>
    </form>
</body>
</html>
WebForm1.aspx
技術分享
using System;
namespace WebDemo
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            label1.InnerText = "被局部刷新了";
            label1.Style.Add("color", "red");

        }
    }
}
WebForm1.aspx.cs
技術分享
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>子級頁</title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:Button ID="Button1" runat="server" Text="刷新父級頁局部" OnClick="Button1_Click" />
    </form>
</body>
</html>
WebForm2.aspx
技術分享
using System;
namespace WebDemo
{
    public partial class WebForm2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            Response.Write("<script language=‘javascript‘>window.opener.document.getElementById(‘Button1‘).click(); </script>");
        }
        
    }
}

WebForm2.aspx.cs

 下載Demo源碼

以上都是轉載部分。。。。

我的項目的實際情況和引子描述基本一致,原作者用的是window.open來彈出窗口。我用的是div包着iframe情況略有不同但是大同小異。

子頁面觸發父頁面局部刷新按鈕事件

protected void Button1_Click(object sender, System.EventArgs e)
		{
            ScriptManager.RegisterStartupScript(Page, this.GetType(), "msg", "parent.window.document.getElementById('txt_tx').value='" + Request.Form["xz"] + "';parent.window.document.getElementById('btnTixi').click();parent.layer.close(parent.layer.getFrameIndex(window.name))", true);
		}

 這里我用了layer框架的彈窗,並且給隱藏的textbox賦值,達到頁面之間傳值的效果。而父頁面也是有一個隱藏的button等待子頁面來觸發,做局部刷新用

<div style="display: none;">
                    <asp:Button ID="btnTixi" runat="server" Text="Button" CausesValidation="false" OnClick="btnTixi_Click" />
                </div>
protected void btnTixi_Click(object sender, EventArgs e)
        {
            xs_fw(this.txt_tx.Text.Trim());
        }

這樣就完成了,點擊子頁面上的某個按鈕來觸發父頁面局部刷新



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM