【问题标题】:Accessing the Parent Window's Content from the child window从子窗口访问父窗口的内容
【发布时间】:2013-08-12 11:13:22
【问题描述】:

单击按钮时我正在打开一个新窗口,然后将此窗口中的内容附加到已打开的窗口中,我正在使用的 jquery 代码是:

    $(".printBtn").on("click", function () {
        var w = window.open("", "Purchase Report", "width=800, height=1100");
        var wi = $(window);

        $(w.document.body).append(wi.find("#datatable_example"));

        return false;
    });

问题是,确实打开了一个新窗口,但父窗口中的内容并未附加到新打开的窗口中。然后我尝试附加wi.find("#datatable_example").html(),但这也不起作用。

任何人都可以看看并告诉我我在这里做错了什么吗?

更新

从“重复问题”中尝试了以下方法,但没有奏效:

    $(".printBtn").on("click", function () {
        var w = window.open("", "Purchase Report", "width=800, height=1100");

        $(w.document).ready(function () {
            $(w.document.body).contents().append($(window).find("#datatable_example"));
        });

        return false;
    });

【问题讨论】:

  • 专业提示,如果要检查选择器是否匹配任何内容,请查看长度(如果没有找到,则为 0):console.log(wi.find("#datatable_example").length)
  • @oleq!那为什么呢?我正在使用一种完全不同的方式来实现这一点。 - 打开一个空的 URL 窗口,即一个没有内容的窗口,因此它不会花费任何时间来加载,对吗? - 我正在尝试访问与子窗口无关的父窗口内容,但仍然遇到无法检索子窗口的问题。
  • @KamranAhmed Er。对不起,你是对的。我在下面发布了答案。

标签: javascript jquery dom javascript-events


【解决方案1】:

问题是,我使用的是var wi = $(window) 而不是var wi = $(window.document)。这是工作代码:

$(".printBtn").on("click", function () {
    var w = window.open("", "Purchase Report", "width=800, height=1100");
    var wi = $(window.document);

    $(w.document.body).append(wi.find("#datatable_example"));

    return false;
});

【讨论】:

    【解决方案2】:

    问题的根源在于同源策略不允许您观察外部域的加载事件。如果您在浏览 SO 时在开发者控制台中尝试此操作,一切都很好:

    var child = window.open( 'http://stackoverflow.com' );
    
    child.onload = function() { 
       alert( 'Popup loaded!' ); // Fired!
    };
    

    但是,如果您尝试从其他域打开页面,则会失败:

    var child = window.open( 'http://stackexchange.com' );
    
    child.onload = function() { 
       // It's not gonna be fired unless you run it from stackexchange.com.
       alert( 'Popup loaded!' ); 
    };
    

    当您调用window.open() 或window.open( '' ) 时会发生同样的事情,因为它试图加载超出您域范围的about:blank 页面,这就是您的浏览器不会触发附加事件的原因(child.addEventListener( 'load' ) 也是如此) )。另请注意,协议也必须匹配。

    解决方法引入了setTimeout 在单独的 JS 线程中运行回调,希望足够晚以在那时准备好 DOM:

    var child = window.open();
    
    setTimeout( function() {
        var doc = child.document,
            p = doc.createElement( 'p' );
    
        p.innerHTML = 'Hello world!';
        doc.body.appendChild( p );
    } );
    

    它在最新的 Chrome 中对我有用,但是在这种边缘情况下,不同的浏览器有时会做一些奇怪的事情,因此如果在你的情况下失败,你可能需要以更大的延迟、顺序检查或其他方式调整此代码。

    所以请继续告诉我们它是否对您有用,因为我很好奇这种解决方法是否适合生产代码;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-04
      • 2013-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-30
      • 1970-01-01
      相关资源
      最近更新 更多