【问题标题】:Javascript pop-up window document is never "ready"Javascript 弹出窗口文档永远不会“准备好”
【发布时间】:2012-07-12 13:49:54
【问题描述】:

我正在使用 Javascript 打开一个空白窗口,用最低限度填充它并注入一个脚本标记以包含 JQuery,但窗口属性 readyState 永远不会超过加载,因此 JQuery 永远不会触发。这是demo on jsFiddle。我不明白为什么弹出窗口没有更新它的 readyState。

var popup = window.open("", "popup", "height=500,width=700");
var doc = popup.document;
doc.write("<!doctype html><html><head></head><body></body></html>");
var script = doc.createElement("script");
script.type = "text/javascript";
script.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js";
script.onload = function() {
  console.log(doc.readyState);
  popup.$(document).ready(function() {
    console.log(doc.readyState);
  });
}
doc.getElementsByTagName("head")[0].appendChild(script);

这是没有 JQuery 的类似代码——readyState 窗口属性的相同问题永远不会超出“加载”范围。

var popup = window.open("", "popup", "height=500,width=700");
var doc = popup.document;
doc.write("<!doctype html><html><head></head><body></body></html>");
console.log(doc.readyState);

【问题讨论】:

  • 我认为这是一个沙盒限制,因为弹出页面 URL 与您的脚本没有相同的域。
  • 空白页(使用“”)不会在同一个域上吗?我在 Chrome 中没有收到任何适用限制的错误。另外,在我的完整代码中,我继续调用弹出窗口的 JavaScript 调用,知道它在技术上已经准备好——即使窗口不这么认为。只是没有我想要的那么干净。
  • 您为什么使用古老的 window.open 而不是使用众多 jQuery 模态对话框之一?
  • 此代码位于我无法控制的窗口的 iFrame 内。如果 iFrame 尺寸太小,此功能允许用户在设置为较大尺寸的弹出窗口中打开内容。

标签: javascript popup readystate


【解决方案1】:

如果您从不设置 URL,则就绪状态不会改变。它将被“初始化”或“加载” - 取决于您的浏览器。您可以通过在弹出窗口的控制台窗口中设置 document.location 来查看此更新,如下所示:

console.log(document.readyState);
document.location = "http://yourdomain.com";
console.log(document.readyState);

如果您将位置发送到域以外的域,则您将没有安全性来修改窗口对象。解决此问题的一种方法是使用 iframe 并设置源 - 如下所示:

var nw = window.open('', "MyWindowID", "fullscreen=no, toolbar=no, menubar=no,status=no,location=no");
var html = '<iframe id="document-{aid}" style="width:100%;height:100%;" src="http://www.google.com"></iframe>';
nw.document.write(html);
nw.focus();

见:https://stackoverflow.com/a/1443839/1220302

对此的注意是尝试将您的弹出窗口包装在 $(popup) 中并挂钩 ready 事件。

这应该适合你:

var popup = window.open("", "popup", "height=500,width=700");
var doc = popup.document;
doc.write("<!doctype html><html><head></head><body></body></html>");
var script = doc.createElement("script");
script.type = "text/javascript";
script.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js";    
$(popup).ready(function(){
    console.log('loaded');
});

【讨论】:

  • 这有点令人困惑,因为如果您将日志更改为console.log(doc.readyState),那么它仍会报告为“正在加载”。当readyState没有改变时,为什么JQuery认为文档已经准备好了?查看 JQuery 脚本,它似乎运行了 readyState。
  • 看起来 readyState 并不是在所有浏览器中都是干净的,并且 JQuery 实际上设置了 DOM 事件处理程序来处理文档就绪。我仍然很好奇为什么从父窗口的 jQuery 调用有效,而不是弹出窗口本身的 JQuery,但它仍然是一个有效的解决方案,所以我将其标记为已接受。
  • 我已经更新了答案,提供了更多关于您可能会觉得有用的信息。
【解决方案2】:

因为没有指向popup 的url,所以它立即准备好了。在window.open 命令完成后,任何对它的“准备就绪”的分配都变得无关紧要了。它永远不会触发,因为已经太晚了。

【讨论】:

  • 它看起来是这样运行的,但是为什么窗口的“readyState”属性仍然设置为“正在加载”? (这就是我在 JQuery 事件之外记录 readyState 的原因。)
  • 实际上,仔细观察一下,我认为popup 不会在您指定的上下文中存在。
  • 也许我用 JQuery 使我的例子复杂化了,但即使 this demo with JQuery removed readyState 也不会改变。
猜你喜欢
  • 2016-02-14
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
  • 2014-08-17
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 2017-10-28
相关资源
最近更新 更多