简体   繁体   English

检测 window 打开的 onload 事件 window.open

[英]Detecting the onload event of a window opened with window.open

 window.popup = window.open($(this).attr('href'), 'Ad', 'left=20,top=20,width=500,height=500,toolbar=1,resizable=0');
 $(window.popup).onload = function()
        {
                alert("Popup has loaded a page");
        };

This doesn't work in any browser I've tried it with (IE, Firefox, Chrome).这在我尝试过的任何浏览器(IE、Firefox、Chrome)中都不起作用。 How can I detect when a page is loaded in the window (like an iframe onload)?如何检测页面何时加载到 window(如 iframe onload)?

var myPopup = window.open(...);
myPopup.addEventListener('load', myFunction, false);

If you care about IE, use the following as the second line instead:如果您关心 IE,请改用以下内容作为第二行:

myPopup[myPopup.addEventListener ? 'addEventListener' : 'attachEvent'](
  (myPopup.attachEvent ? 'on' : '') + 'load', myFunction, false
);

As you can see, supporting IE is quite cumbersome and should be avoided if possible .正如你所看到的,支持IE是相当繁琐的,应尽可能避免。 I mean, if you need to support IE because of your audience, by all means, do so.我的意思是,如果你因为你的观众而需要支持 IE,一定要这样做。

If the pop-up's document is from a different domain, this is simply not possible.如果弹出窗口的文档来自不同的域,这是不可能的。

Update April 2015: I was wrong about this: if you own both domains, you can use window.postMessage and the message event in pretty much all browsers that are relevant today . 2015 年 4 月更新:我错了:如果您拥有两个域,则可以在当今几乎所有相关的浏览器使用window.postMessagemessage事件

If not, there's still no way you'll be able to make this work cross-browser without some help from the document being loaded into the pop-up.如果没有,如果没有将文档加载到弹出窗口中的帮助,您仍然无法使这项工作跨浏览器工作。 You need to be able to detect a change in the pop-up that occurs once it has loaded, which could be a variable that JavaScript in the pop-up page sets when it handles its own load event, or if you have some control of it you could add a call to a function in the opener.您需要能够检测弹出窗口加载后发生的更改,这可能是弹出页面中的 JavaScript 在处理自己的load事件时设置的变量,或者如果您对您可以在 opener 中添加对函数的调用。

As noted at Detecting the onload event of a window opened with window.open , the following solution is ideal:检测使用 window.open 打开的窗口的 onload 事件所述,以下解决方案是理想的:

/* Internet Explorer will throw an error on one of the two statements, Firefox on the other one of the two. */
(function(ow) {
    ow.addEventListener("load", function() { alert("loaded"); }, false);
    ow.attachEvent("onload", function() { alert("loaded"); }, false);
})(window.open(prompt("Where are you going today?", location.href), "snapDown"));

Other comments and answers perpetrate several erroneous misconceptions as explained below.如下所述,其他评论和答案犯下了几个错误的误解。

The following script demonstrates the fickleness of defining onload .以下脚本演示了定义onload Apply the script to a "fast loading" location for the window being opened, such as one with the file: scheme and compare this to a "slow" location to see the problem: it is possible to see either onload message or none at all (by reloading a loaded page all 3 variations can be seen).将脚本应用于正在打开的窗口的“快速加载”位置,例如带有file: scheme 并将其与“慢”位置进行比较以查看问题:可能会看到onload消息或根本没有消息(通过重新加载加载的页面,可以看到所有 3 种变化)。 It is also assumed that the page being loaded itself does not define an onload event which would compound the problem.还假设正在加载的页面本身没有定义会使问题复杂化的onload事件。

The onload definitions are evidently not "inside pop-up document markup": onload定义显然不是“内部弹出文档标记”:

var popup = window.open(location.href, "snapDown");
popup.onload = function() { alert("message one"); };
alert("message 1 maybe too soon\n" + popup.onload);
popup.onload = function() { alert("message two"); };
alert("message 2 maybe too late\n" + popup.onload);

What you can do:你可以做什么:

  • open a window with a "foreign" URL打开一个带有“外部”URL 的窗口
  • on that window's address bar enter a javascript: URI -- the code will run with the same privileges as the domain of the "foreign" URL在该窗口的地址栏上输入一个javascript: URI -- 代码将以与“外部”URL 的域相同的权限运行
    The javascript: URI may need to be bookmarked if typing it in the address bar has no effect (may be the case with some browsers released around 2012)如果在地址栏中键入javascript: URI 无效,则可能需要将其添加为书签(可能是 2012 年左右发布的某些浏览器的情况)

Thus any page, well almost, irregardless of origin, can be modified like:因此,几乎任何页面,无论其来源如何,都可以修改为:

if(confirm("wipe out links & anchors?\n" + document.body.innerHTML))
    void(document.body.innerHTML=document.body.innerHTML.replace(/<a /g,"< a "))

Well, almost:嗯,差不多:

jar:file:///usr/lib/firefox/omni.ja!/chrome/toolkit/content/global/aboutSupport.xhtml , Mozilla Firefox's troubleshooting page and other Jar archives are exceptions. jar:file:///usr/lib/firefox/omni.ja!/chrome/toolkit/content/global/aboutSupport.xhtml 、Mozilla Firefox 的故障排除页面和其他 Jar 存档是例外。

As another example, to routinely disable Google's usurping of target hits, change its rwt function with the following URI:再举一个例子,要定期禁用 Google 篡夺目标点击,请使用以下 URI 更改其rwt函数:

javascript: void(rwt = function(unusurpURL) { return unusurpURL; })

(Optionally Bookmark the above as eg "Spay Google" ("neutralize Google"?) (可选地将上述内容添加为例如“Spay Google”(“中和 Google”?)

This bookmark is then clicked before any Google hits are clicked, so bookmarks of any of those hits are clean and not the mongrelized perverted aberrations that Google made of them.然后在单击任何 Google 命中之前单击此书签,因此任何这些命中的书签都是干净的,而不是 Google 对它们造成的杂乱无章的畸变。

Tests done with Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:11.0) Gecko/20100101 Firefox/11.0 UA string.使用Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:11.0) Gecko/20100101 Firefox/11.0 UA 字符串完成的测试。

It should be noted that addEventListener in Firefox only has a non-standard fourth, boolean parameter, which if true allows untrusted content triggers to be instantiated for foreign pages.需要注意的是,Firefox 中的addEventListener只有一个非标准的第四个布尔参数,如果为true ,则允许为外部页面实例化不受信任的内容触发器。

Reference:参考:
element.addEventListener | element.addEventListener | Document Object Model (DOM) | 文档对象模型 (DOM) | MDN: MDN:
Interaction between privileged and non-privileged pages | 特权和非特权页面之间的交互| Code snippets | 代码片段 | MDN: MDN:

This did the trick for me;这对我有用; full example:完整示例:

HTML: HTML:

<a href="/my-popup.php" class="import">Click for my popup on same domain</a>

Javascript: Javascript:

(function(){
    var doc = document;

    jQuery('.import').click(function(e){
        e.preventDefault();
        window.popup = window.open(jQuery(this).attr('href'), 'importwindow', 'width=500, height=200, top=100, left=200, toolbar=1');

        window.popup.onload = function() {
            window.popup.onbeforeunload = function(){
                doc.location.reload(true); //will refresh page after popup close
            }
        }
    });
})();

onload事件处理程序必须在 popup 的 HTML <body>标记内。

First of all, when your first initial window is loaded, it is cached .首先,当你的第一个初始窗口被加载时,它被缓存 Therefore, when creating a new window from the first window, the contents of the new window are not loaded from the server, but are loaded from the cache.因此,从第一个窗口创建窗口时,窗口的内容不是从服务器加载,而是从缓存加载。 Consequently, no onload event occurs when you create the new window.因此,创建窗口时不会发生onload事件。

However, in this case, an onpageshow event occurs.但是,在这种情况下,会发生onpageshow事件。 It always occurs after the onload event and even when the page is loaded from cache.它总是在onload事件之后发生,甚至在从缓存加载页面时也是如此。 Plus, it now supported by all major browsers.此外,现在所有主要浏览器都支持它。

 window.popup = window.open($(this).attr('href'), 'Ad', 'left=20,top=20,width=500,height=500,toolbar=1,resizable=0');
 $(window.popup).onpageshow = function() {
     alert("Popup has loaded a page");
 };

The w3school website elaborates more on this: w3school 网站对此进行了详细说明:

The onpageshow event is similar to the onload event, except that it occurs after the onload event when the page first loads. onpageshow 事件与onload事件类似,不同之处在于它发生在页面首次加载时的 onload 事件之后。 Also, the onpageshow event occurs every time the page is loaded, whereas the onload event does not occur when the page is loaded from the cache.此外,每次加载页面时都会发生onpageshow事件,而从缓存加载页面时不会发生 onload 事件。

The core problem seems to be you are opening a window to show a page whose content is already cached in the browser.核心问题似乎是您正在打开一个窗口以显示其内容已缓存在浏览器中的页面。 Therefore no loading happens and therefore no load-event happens.因此不会发生加载,因此不会发生加载事件。

One possibility could be to use the 'pageshow' -event instead, as described in:一种可能性是使用 'pageshow' -event 代替,如下所述:

https://support.microsoft.com/en-us/help/3011939/onload-event-does-not-occur-when-clicking-the-back-button-to-a-previou https://support.microsoft.com/en-us/help/3011939/onload-event-does-not-occur-when-clicking-the-back-button-to-a-previou

Simple solution:简单的解决方案:

new_window = window.open(...);
new_window.document.write('<body onload="console.log(1);console.log(2);></body>');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM