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

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

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.

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.

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:

This did the trick for me; full example:
HTML:
Click for my popup on same domain
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 event handler must be inside popup's HTML <body> markup.

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.

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

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

Related

Document ready form submission and browser history

I have the following code in my page to submit the form on the page automatically when the DOM is ready:
$(function () {
$('form').submit();
});
However, on the next page if the user clicks back on their browser it goes back to the page before this one rather than the page with this code on (with Chrome/IE anyway). i.e. the page with the form on is missing in the browser history.
This is great, although I wondered is this something all modern browsers now do? I am looking for an answer that cites official sources such as from internet standards documents or from browser vendors that state the mechanism they have implemented.
This appears to only happen if I call the submit() function in the DOM ready or Window load events.
e.g. this code will show the form page in browser history after the page is clicked (back/forward):-
document.addEventListener('click', function () { document.forms[0].submit(); }, false);
the following snippets won't:-
document.addEventListener('DOMContentLoaded', function () { document.forms[0].submit(); }, false);
window.addEventListener('load', function() { document.forms[0].submit(); }, false);
window.onload = function () { document.forms[0].submit(); };
I've dealt with this before. I did not want the back button to take
the user back to previous page. Using onbeforeunload solved the
issue for me...
But your issue is related to the following concepts
Browsing Context
Session History
Replacement Enabled (flag)
A "Browsing Context" is an environment in which "Document" objects
are presented to the user.
The sequence of "Document"s in a "Browsing Context" is its "Session History". The
"Session History" lists these "Document"s as flat entries.
"Replacement Enabled" comes into effect when we propagate from one "Document" to another in the "Session History". If the traversal was initiated with "Replacement Enabled", the entry immediately before the specified entry (in the "Session History") is removed.
Note A tab or window in a Web browser typically contains a browsing context, as does an iframe or frames in a frameset.
Logically thinking, by calling any of these
document.addEventListener( 'DOMContentLoaded', function() {document.forms[0].submit();}, false );
window.addEventListener( 'load', function() {document.forms[0].submit();}, false );
window.onload = function() {document.forms[0].submit();};
you are suggesting the browser to perform #3, because what those calls mean
is that propagate away from the page as soon as it loads. Even to me that code is
obviously :) asking to be cleared off from the "Session History".
Further reading...
onbeforeunload
browsers
browsing-context
unloading-documents
replacement-enabled
Since this code leaves the page in the history when responding to the click event:-
document.addEventListener('click', function () { document.forms[0].submit(); }, false);
and the following pieces of code do not leave the page in history (DOMContentLoaded, and window onload events):-
document.addEventListener('DOMContentLoaded', function () { document.forms[0].submit(); }, false);
window.addEventListener('load', function() { document.forms[0].submit(); }, false);
window.onload = function () { document.forms[0].submit(); };
it can be assumed that modern browsers do not record a navigation history for page navigation that occurs within the window load or document ready handlers.
When the user hits the back button, the browser shows the cached copy of the page. Form submit doesn't cache the page therefore it doesn't show up in your history.
Yes, redirecting from an onload event handler causes the new URL to replace the one you leave in the history (and thus doesn't add a useless entry). But that's not the only trigger for that replacement, it may also be caused by any location change occurring fast enough, this delay being designed to avoid polluting the history in case of JavaScript based re-directions.
It is very hard to find any specification on that topic but on Firefox this delay seems to be 15 seconds. Here's a mention of this delay in bugzilla from one of the moz developers :
Mozilla uses a threshold of 15 seconds to decide if a page should
stay in history or not. If a site uses and
redirects to another site with in 15 seconds OR redirects to another
page in onLoadHandler() etc ..., the redirected page will replace
(and thereby eliminating) the redirecting page from history. If the
redirection happens after 15 seconds, the redirecting page stays in
history.
One may argue about the
time limit. But this is just something we thought was a reasonable number

Diagnosing body.onload not being called

I have some web pages which rely on body.onload (or, equivalently, window.onload) to set them up properly. Sometimes onload is not being called.
Is there a trick with some web browser (ideally Chrome, where this apparently happens most often) which will tell me what exactly is preventing the page from loading successfully?
Clue: this rarely (maybe even never) happens when I hit F5 to reload the whole page, but more generally it happens if a page has been arrived-at by clicking a link or pasting the url into the address bar. Is there a quirk of onload semantics that might be tripping me up?
N.B. The scripts themselves are not producing any errors in the console.
I think you want window.onload
I have tested such cases, and none of the following will work:
var callback = function() { alert("Body loaded"); };
$("body").load(callback);
document.body.addEventListener("load",callback,false);
However, document.body.onload seems to work fine. Make sure that body is correctly namespaced:
document.body //<body>
body //Reference error
If you're talking about:
<body onload="callback();"></body>
Then go back and review your code, because it should work.
Personally, I suggest using the load event of the window object or a framework's ready event.
//Execute when the window is loaded
var callback = function() {
//Your code goes here...
};
if (window.addEventListener) window.addEventListener("load",callback,false);
else window.attachEvent("load",callback);
With jQuery, you only need the following:
$(window).load(callback);
jQuery's ready event is as follows:
$(document).ready(callback);
//Or just:
$(callback);
MooTools use this:
window.addEvent("domready",callback);
And different libraries all have their own way.

Which XUL element to use when a url is entered and loaded for calling JS?

I am developing a Firefox add-on using XUL Overlay and want to call a specific js when the current page loads after entering the URL. I want to know which XUL element would be affected and should be used to call said JS, such as page or tab or window or ??? Also, which event would be best for the element? Or is my logic wrong?
Also,the js's function is to record tab title and/or url so i need to know when to call js and with corresponding event. Thanks.. :)
The XUL element you should be watching is the tabbrowser. In the browser window (which means also in overlays applied to the browser window) it can be accessed via the global gBrowser variable. If you want to know when a page finishes loading you can listen to the DOMContentLoaded event. Something like this (untested code):
// Declare an own namespace for extension's functions to avoid
// name conflicts with other extensions.
var MyExtension = {};
MyExtension.init = function()
{
gBrowser.addEventListener("DOMContentLoaded", MyExtension.onPageLoad, false);
};
MyExtension.onPageLoad = function(event)
{
// Get the document that loaded
var doc = event.originalTarget;
// Ignore frames that load
if (doc.defaultView != doc.defaultView.parent)
return;
// Ignore if this isn't the active tab
var browser = gBrowser.getBrowserForDocument(doc);
if (browser != gBrowser.selectedBrowser)
return;
alert("Page loaded in current tab: " + doc.defaultView.location.href);
};
// Wait for the browser window to finish loading before adding event listeners
window.addEventListener("load", MyExtension.init, false);
If you want to get notified earlier, when the address displayed in the URL bar changes, you can use a progress listener instead. You want to implement the method onLocationChange of the progress listener and leave the other methods empty. Note that this method is also called when the user switches to a different tab (this also causes a location bar change). Also: the parameter aURI passed to onLocationChange is an nsIURI instance. If you want the URL as a string you should look at aURI.spec.

After travelling back in Firefox history, JavaScript won't run

When I use the back button on Firefox to reach a previously visited page, scripts on that page won't run again.
Is there any fix/workaround to have the scripts execute again when viewing the page the second time?
Please note that I have tested the same pages on Google Chrome and Internet Explorer and they work as intended.
Here are the files and the steps I used to test the problem:
(navigate to 0.html, click to get to 1.html, back button)
0.html
<html><body>
<script>
window.onload = function() { alert('window.onload alert'); };
alert('inline alert');
</script>
Click Me!
</body></html>
1.html
<html><body>
<p>Go BACK!</p>
</body></html>
Set an empty function to be called on window.onunload:
window.onunload = function(){};
e.g.
<html><body>
<script type="text/javascript">
window.onload = function() { alert('window.onload alert'); };
window.onunload = function(){};
alert('inline alert');
</script>
Click Me!
</body></html>
Source:
http://www.firefoxanswer.com/firefox/672-firefoxanswer.html (Archived Version)
When I use the back button on Firefox to reach a previously visited page, scripts on that page won't run again.
That's correct and that's a good thing.
When you hit a link in Firefox (and Safari, and Opera), it does not immediately destroy your page to go onto the next one. It keeps the page intact, merely hiding it from view. Should you hit the back button, it will then bring the old page back into view, without having to load the document again; this is much faster, resulting in smoother back/forward page transitions for the user.
This feature is called the bfcache.
Any content you added to the page during the user's previous load and use of it will still be there. Any event handlers you attached to page elements will still be attached. Any timeouts/intervals you set will still be active. So there's rarely any reason you need to know that you have been hidden and re-shown. It would be wrong to call onload or inline script code again, because any binding and content generation you did in that function would be executing a second time over the same content, with potentially disastrous results. (eg. document.write in inline script would totally destroy the page.)
The reason writing to window.onunload has an effect is that the browsers that implement bfcache have decided that — for compatibility with pages that really do need to know when they're being discarded — any page that declares an interest in knowing when onunload occurs will cause the bfcache to be disabled. That page will be loaded fresh when you go back to it, instead of fetched from the bfcache.
So if you set window.onunload= function() {};, what you're actually doing is deliberately breaking the bfcache. This will result in your pages being slow to navigate, and should not be used except as a last resort.
If you do need to know when the user leaves or comes back to your page, without messing up the bfcache, you can trap the onpageshow and onpagehide events instead:
window.onload=window.onpageshow= function() {
alert('Hello!');
};
You can check the persisted property of the pageshow event. It is set to false on initial page load. When page is loaded from cache it is set to true.
window.onpageshow = function(event) {
if (event.persisted) {
alert("From bfcache");
}
};
For some reason jQuery does not have this property in the event. You can find it from original event though.
$(window).bind("pageshow", function(event) {
if (event.originalEvent.persisted) {
alert("From bfcache");
}
});
In my case window.onunload with an empty function didn't help (I tried to set a value for dropdown when user uses backwards button). And window.onload didn't work for other reason - it was overridden by <body onload="...">.
So I tried this using jQuery and it worked like a charm:
$(window).on('pageshow', function() { alert("I'm happy"); });
Wire in an "onunload" event that does nothing:
<html><body>
<script type="text/javascript">
window.onload = function() { alert('window.onload alert'); };
window.onunload = function(){};
alert('inline alert');
</script>
Click Me!
</body></html>
As far as i know Firefox does not fire onLoad event on back.
It should trigger onFocus instead based from this link here.
A simple way to cause a page to execute JavaScript when the user navigates back to it using browser history is the OnPopState event. We use this to pause and replay the video on our home page (https://fynydd.com).
window.onpopstate = function() {
// Do stuff here...
};
for some cases like ajax operations url change listener can be used
$(window).on('hashchange', function() {
....
});

In XUL, how do I know a browser-tag has finished loading?

I'm developing a firefox extension based on this tutorial which is a FF 2.0 extension (second part of the tutorial is at this url)
The main thing that is important is that it uses
<iframe id="contentview" src="http://www.ibm.com/developerworks/web" flex="2"/>
In the backend code, when clicking the GO button, this happens:
contentview.contentDocument.location.href = urlbox.value;
//Use Firefox XPath to get the raw text of the document
var doctext = contentview.contentDocument.evaluate(
"string(.)", document, null, XPathResult.STRING_TYPE, null).stringValue;
I get an error with the xpath, but that's not my question. The issue I have with FF 3.0 is that the contentDocument value refers to the old site loaded, not to the one loaded by the href-change.
So my question is: how can I create a similar window, but be notified someone when the loaded document is complete, so I can access its DOM?
Updated:
first you need to handle the load event of the window then you add an event listener to the iframe element
window.addEventListener("load",Listen,false);
function Listen()
{
var frame = document.getElementById("contentview");
frame.addEventListener("DOMContentLoaded", DomLoadedEventHandler, true);
}
function DomLoadedEventHandler() {
var frame = document.getElementById("contentview");
alert(frame.contentDocument.location.href);
}
replace "DomLoadedEventHandler" with your event handler name.
I recommend that you take a look at the official site of Mozilla to learn everything about Firefox extensions
http://developer.mozilla.com

Categories