将document.ready绑定到弹出窗口

时间:2011-11-16 21:01:12

标签: javascript jquery document-ready

由于jQuery绑定document.ready事件的方式,应该简单的代码不是:

var w = window.open(someSameOriginLocation,'');
$(w).ready(function () { //alternatively selector could be $(w.document)
  console.log('popout ready');
});

问题

  • 当父窗口准备好而不是子窗口
  • 时执行回调 回调中的
  • this是对w.opener.document
  • 的引用

是否有一种相当简单的跨浏览器方式使用jQuery将ready事件(或类似)绑定到不同的窗口上下文?

2 个答案:

答案 0 :(得分:0)

5年前我问这个问题时,我没有听说过承诺。最近发布了jQuery 1.7,并在今年早些时候的1.5中引入了Deferred。这早于一年后发布的Promises/A+规范。

我说这一切都是因为当时我无法识别jQuery的$(document).ready(...)因为它是什么。

它被绑定为一个事件,并将一个回调作为一个事件,并且jQuery API将其视为一个事件,所以我错误地认为它是一个事件,虽然是一个特殊事件。

文件就绪不是一个事件。 这是一个承诺。

所有这一切,我的错误是试图遵循jQuery的领导并创造一个奇特的事件,当我应该做的是使用一个承诺(不要介意他们不存在于JS世界)。

尽管如此,在现代浏览器中支持任何窗口引用的document.ready类行为非常简单。我有时间优势,因为许多旧问题已被删除,新的浏览器功能(例如Promise)大大减少了实现ready功能的工作量。

我对此问题的解决方案如下:

function ready(win) {
    return new Promise(function (resolve) {
        function checkReady() {
            if (win.document.readyState === 'complete') {
                resolve();
            }
        }

        win.document.addEventListener('DOMContentLoaded', checkReady, false);
        win.addEventListener('load', checkReady, false);
        checkReady();
    });
}

可以用作:

ready(window).then(function () {
  //...do stuff
});

或者如果您正在使用window.open

ready(open('/your/file.html', ...)).then(function () {
  //.../your/file.html is ready
});

答案 1 :(得分:-2)

JavaScript安全策略不允许这样做。例如,您收到控制台错误

Unsafe JavaScript attempt to access frame with URL http://www.example.com/ from frame with URL http://www.example.org/. Domains, protocols and ports must match.

在调用window.open和设置同一窗口的onload函数之间有一个暂停是必要的。 window.open之后立即调用该窗口没有属性。也许你必须反复使用setInterval这样做(不要忘记clearInterval) 在jsfiddle中尝试这个(这是我最好的猜测)

function func() {

    var w = window.open('http://fiddle.jshell.net/','windowname');

    setTimeout(function() {
        w.onload = function () {
            $(w).ready(function() {
                console.log(w.name)
            });
        };
    },1000)
}

http://jsfiddle.net/HerrSerker/fTjTr/8/