Detecting the onload event of a window opened with window.open

152,578

Solution 1

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.

Solution 2

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.

Solution 3

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:

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

Solution 5

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

Share:
152,578
Christopher Tarquini
Author by

Christopher Tarquini

Updated on July 09, 2022

Comments

  • Christopher Tarquini
    Christopher Tarquini almost 2 years
     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
    Christopher Tarquini almost 14 years
    Anyway I can do this cross-domain?
  • Delan Azabani
    Delan Azabani almost 14 years
    Unfortunately not. For security reasons, browsers disable JavaScript object interaction across different domains.
  • Delan Azabani
    Delan Azabani almost 14 years
    Then just use a tertiary conditional. I'll add it.
  • Jerod Venema
    Jerod Venema over 13 years
    A simple way to check it to monitor the availability of a JS function in the other page in a setTimeout() call.
  • MushinNoShin
    MushinNoShin over 11 years
    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
    MushinNoShin over 11 years
    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.
  • ekim
    ekim over 11 years
    The referenced answer was the direct share link to a posted answer to this very question - it would have been better to ... done! ...
  • ekim
    ekim over 11 years
    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...!
  • Pete Martin
    Pete Martin about 10 years
    Your writing style is very difficult to read. My brain hurt trying to discern the meaning in this answer. Brevity is no bad thing.
  • user359519
    user359519 almost 10 years
    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
    user359519 almost 10 years
    var w = window.open(targetUrl, "_blank"); w[w.addEventListener ? 'addEventListener' : 'attachEvent']( (w.attachEvent ? 'on' : '') + 'load', doPrint(w), false );
  • user359519
    user359519 almost 10 years
    function doPrint(w) { if (navigator.userAgent.search("MSIE") >= 0) { console.log("Browser is InternetExplorer"); w.print(); } else { w.onload = function() { w.print(); } } }
  • James
    James about 9 years
    According to this post stackoverflow.com/questions/25098021/… it is possible, but you must own both domains.
  • Ben Muircroft
    Ben Muircroft over 7 years
    should be said that this will only work if the domains are both the same
  • Wishper
    Wishper almost 7 years
    Sorry, I'm having trouble with this could you tell me why it is not working?jsfiddle.net/9Lmdwb5y
  • Breeno
    Breeno over 6 years
    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.
  • user5886944
    user5886944 about 6 years
    Is the self calling function really needed !?
  • lschult2
    lschult2 about 2 years
    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?