菜鸟解决“子页面关闭刷新父页面局部”问题的历程

 

引子

      昨天晚上做一个项目,遇到的一个问题,这个项目是一个在线考试系统,新建一份试卷的页面,要添加一些试题策略。点击添加试题策略,弹出添加策略的页面,策略编辑好之后提交,添加策略页关闭,当前添加试题页面策略列表刷新。那么就遇到一个问题,在“添加试卷页”中点击“添加策略”按钮弹出添加策略页,添加策略后,父页面只能局部刷新(整体刷新会丢掉页面输入框未保存的数据)。

      综上总结,浓缩成一句话啊,就是“父页面打开子页面,子页面完成操作后触发父页面的事件。”

过程

      我在百度和必应里面搜一下,很多解决方案是用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源码

 

 

posted on 2015-07-24 15:47  盛强  阅读(6016)  评论(0编辑  收藏  举报

导航