57
 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). How can I detect when a page is loaded in the window (like an iframe onload)?

Christopher Tarquini
  • 11,176
  • 16
  • 55
  • 73

8 Answers8

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

If you care about IE, use the following as the second line instead:

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. I mean, if you need to support IE because of your audience, by all means, do so.

Delan Azabani
  • 79,602
  • 28
  • 170
  • 210
  • 1
    Anyway I can do this cross-domain? – Christopher Tarquini Jun 13 '10 at 06:45
  • 3
    Unfortunately not. For security reasons, browsers disable JavaScript object interaction across different domains. – Delan Azabani Jun 13 '10 at 07:24
  • 2
    Then just use a tertiary conditional. I'll add it. – Delan Azabani Jun 14 '10 at 04:46
  • 1
    I spent hours looking for a solution, and this is the only one that worked for me. One thing to notes is that Firefox seems to open the print dialog box before completely loading the page. This will result in printing a blank page. I got around this by detecting the browser, and then using an onload event if needed. This may not be the best approach, but it works for me. Here's my code: – user359519 May 28 '14 at 21:36
  • 1
    var w = window.open(targetUrl, "_blank"); w[w.addEventListener ? 'addEventListener' : 'attachEvent']( (w.attachEvent ? 'on' : '') + 'load', doPrint(w), false ); – user359519 May 28 '14 at 21:38
  • 1
    function doPrint(w) { if (navigator.userAgent.search("MSIE") >= 0) { console.log("Browser is InternetExplorer"); w.print(); } else { w.onload = function() { w.print(); } } } – user359519 May 28 '14 at 21:38
  • Sorry, I'm having trouble with this could you tell me why it is not working?https://jsfiddle.net/9Lmdwb5y/ – Wishper May 17 '17 at 13:23
  • Any ideas of what do do when the target is not HTML? (e.g. PDF). Is there any way to tell when that window is done loading? – lschult2 Apr 08 '22 at 19:36
25

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.

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.

Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • 1
    A simple way to check it to monitor the availability of a JS function in the other page in a setTimeout() call. – Jerod Venema Aug 25 '10 at 13:49
  • According to this post http://stackoverflow.com/questions/25098021/securityerror-blocked-a-frame-with-origin-from-accessing-a-cross-origin-frame it is possible, but you must own both domains. – James Apr 28 '15 at 23:07
6

As noted at Detecting the onload event of a window opened with window.open, the following solution is ideal:

/* 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. 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). It is also assumed that the page being loaded itself does not define an onload event which would compound the problem.

The onload definitions are evidently not "inside pop-up document markup":

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
  • 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
    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)

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.

As another example, to routinely disable Google's usurping of target hits, change its rwt function with the following URI:

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

(Optionally Bookmark the above as e.g. "Spay Google" ("neutralize 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.

Tests done with Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:11.0) Gecko/20100101 Firefox/11.0 UA string.

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.

Reference:
element.addEventListener | Document Object Model (DOM) | MDN:
Interaction between privileged and non-privileged pages | Code snippets | MDN:

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
ekim
  • 118
  • 1
  • 2
  • 8
    There are a lot of sentences in this answer which say one thing and then are followed by another sentence correcting the previous. This causes it to be difficult to follow. There's good information here, it's just hard to see. You'd get more upvotes by speaking more clearly. – MushinNoShin Sep 30 '12 at 17:37
  • Also, if this question is answered by another question, perhaps it's worth flagging it as a duplicate of that other question and directing the asker to the other question in a comment. – MushinNoShin Sep 30 '12 at 17:38
  • The referenced answer was the direct `share` link to a posted answer to this very question - it would have been better to ... done! ... – ekim Oct 01 '12 at 02:39
  • 2
    upvotes per se are not a concern - obfuscation? hopefully nothing is directly contradictory - "perpetration of misconceptions" refers to previous comments and answers about x-site scripting and origination policies and hopefully not by this answer! - the prose is hopefully qualified and verified more succinctly and precisely by the empirical evidence of running the functional code examples - `ow`! (**O** pen **W** indow or should that be `function(ouch)`, a pun in reference to the untreated error condition in the 1st example!) the prose is quite pointed, if writing it hurt then reading it...! – ekim Oct 01 '12 at 03:14
  • 4
    Your writing style is very difficult to read. My brain hurt trying to discern the meaning in this answer. Brevity is no bad thing. – Pete Martin Mar 05 '14 at 11:52
  • Is the self calling function really needed !? – user5886944 Mar 22 '18 at 10:04
4

This did the trick for me; full example:

HTML:

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

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
            }
        }
    });
})();
1

onload event handler must be inside popup's HTML <body> markup.

Thevs
  • 3,189
  • 2
  • 20
  • 32
  • This was the only way I could trigger it, tried just about every other way possible - thanks. `$(popup).find('body').attr('onload', 'window.print();');` worked in the end. – Breeno Sep 17 '17 at 13:01
1

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.

However, in this case, an onpageshow event occurs. It always occurs after the onload event and even when the page is loaded from cache. 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:

The onpageshow event is similar to the onload event, except that it occurs after the onload event when the page first loads. 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.

Udo E.
  • 2,665
  • 2
  • 21
  • 33
0

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:

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

Panu Logic
  • 2,193
  • 1
  • 17
  • 21
-2

Simple solution:

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