zoukankan      html  css  js  c++  java
  • 菜鸟解决“子页面关闭刷新父页面局部”问题的历程

    引子

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

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

    过程

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

    这样就完成了,点击子页面上的某个按钮来触发父页面局部刷新


  • 相关阅读:
    with ,Row_Number,DateDiff,DateAdd用法学习
    jmeter 读取mysql数据库
    fidder 自动保存请求内容
    redis 常用方法整理
    解决:EXCEL复制粘贴,精度丢失
    MYSQL 创建常见问题
    MYSQL 存储过程、函数、临时表、游标
    MYSQL 测试常用语句使用技巧
    3-6
    selenium3 下载、配置
  • 原文地址:https://www.cnblogs.com/yanergui/p/5624771.html
Copyright © 2011-2022 走看看