Best practice for using window.onload
Asked Answered
V

7

40

I develop Joomla websites/components/modules and plugins and every so often I require the ability to use JavaScript that triggers an event when the page is loaded. Most of the time this is done using the window.onload function.

My question is:

  1. Is this the best way to trigger JavaScript events on the page loading or is there a better/newer way?
  2. If this is the only way to trigger an event on the page loading, what is the best way to make sure that multiple events can be run by different scripts?
Verdha answered 17/2, 2009 at 23:12 Comment(0)
G
46

window.onload = function(){}; works, but as you might have noticed, it allows you to specify only 1 listener.

I'd say the better/newer way of doing this would be to use a framework, or to just to use a simple implementation of the native addEventListener and attachEvent (for IE) methods, which allows you to remove the listeners for the events as well.

Here's a cross-browser implementation:

// Cross-browser implementation of element.addEventListener()
function listen(evnt, elem, func) {
    if (elem.addEventListener)  // W3C DOM
        elem.addEventListener(evnt,func,false);
    else if (elem.attachEvent) { // IE DOM
         var r = elem.attachEvent("on"+evnt, func);
         return r;
    }
    else window.alert('I\'m sorry Dave, I\'m afraid I can\'t do that.');
}

// Use: listen("event name", elem, func);

For the window.onload case use: listen("load", window, function() { });


EDIT I'd like to expand my answer by adding precious information that was pointed by others.

This is about the DOMContentLoaded (Mozilla, Opera and webkit nightlies currently support this) and the onreadystatechange (for IE) events which can be applied to the document object to understand when the document is available to be manipulated (without waiting for all the images/stylesheets etc.. to be loaded).

There are a lot of "hacky" implementations for cross-browsers support of this, so I strongly suggest to use a framework for this feature.

Generally answered 17/2, 2009 at 23:15 Comment(3)
I'd like to strongly promote jQuery's .ready() function: api.jquery.com/readySeptilateral
+1 for "1 listener only", this was exactly the hint I needed right now!Kaminsky
i like the alert message :DDashing
S
13

The window.onload events are overridden on multiple creations. To append functions use the window.addEventListener(W3C standard) or the window.attachEvent(for IE). Use the following code which worked.

if (window.addEventListener) // W3C standard
{
  window.addEventListener('load', myFunction, false); // NB **not** 'onload'
} 
else if (window.attachEvent) // Microsoft
{
  window.attachEvent('onload', myFunction);
}
Stillmann answered 21/8, 2012 at 14:24 Comment(0)
M
10

Modern javascript frameworks have introduced the idea of a "document ready" event. This is an event that will fire when the document is ready to have DOM manipulations performed on it. The "onload" event fires only after EVERYTHING on the page has loaded.

Along with the "document ready" event, the frameworks have provided a way to queue up multiple bits of Javascript code and functions to run when the event fires.

So, if you're opposed to frameworks, the best way to go about this is to implement your own document.onload queue.

If you're not opposed to frameworks, then you'll want to look into jQuery and document.ready, Prototype and dom:loaded, Dojo and addOnLoad or Google for [your framework] and "document ready",.

If you haven't picked a framework but are interested, jQuery is a good place to start. It doesn't change any of Javascript's core functionality, and will generally stay out of your way and let you do things as you like when you want to.

Macedonian answered 17/2, 2009 at 23:44 Comment(4)
any good reference to onload queue implementations, or more explanation of the different between document ready and onload event?Ornithomancy
I don't want to get in a content dispute, but libraries like jQuery are really not frameworks. See https://mcmap.net/q/15613/-is-jquery-a-javascript-library-or-framework-closed/1348195Headgear
I can see both sides of this but the way web developers use jQuery it's more of a framework, irrespective of how the project self describes. This seems like a matter of opinion, point of view, and authorship of the answer to me — especially since I'm referring to the wider world of javascript and the document.ready techniques. No malice or argument intended.Macedonian
Sure, Stack Overflow lets you write down anything you want as an answer and other than that the answer sounds ok. However, things are well defined and that part of the answer is objectively wrong. The fact, as the answer describes it "it doesn't change any of Javascript's core functionality, and will generally stay out of your way and let you do things as you like when you want to" is precisely why it is a library and not a framework. jQuery and similar DOM manipulation libraries do not perform inversion of control, they just provide utilities for writing code. No Hollywood method :)Headgear
L
2

Joomla ships with MooTools, so you'll find it easiest to use the MooTools library for your additional code. MooTools ships with a custom event called domready that fires when the page is loaded and the document tree is parsed.

window.addEvent( domready, function() { code to execute on load here } );

More information about MooTools can be found here. Joomla 1.5 currently ships with MT1.1 while the Joomla 1.6 alpha will include MT1.2

Lampley answered 24/6, 2009 at 19:17 Comment(1)
This answer was valid for its time, but in newer versions of Joomla JQuery is used.Willner
J
1

Personally, I prefer this method. Not only does it allow you to have multiple onload functions, but if some script had defined it before you got to it, this method is nice enough to handle that... The only problem left is if a page loads several script which does not use the window.addLoad() function; but that is their problem :).

P.S. Its also great if you want to "chain" more functions later on.

Joviality answered 18/2, 2009 at 3:26 Comment(0)
D
1

This is the dirty but shorter way :P

function load(){
   *code*
}

window[ addEventListener ? 'addEventListener' : 'attachEvent' ]
( addEventListener ? 'load' : 'onload', function(){} )
Dashing answered 14/9, 2012 at 9:34 Comment(0)
D
0

As of I always include jQuery/bootstrap JS files on bottom of document and have no acces to $ over the document, I developed a tiny "init" plugin which is one and only JS script I include on very top of my pages:

window.init = new function() {
    var list = [];

    this.push = function(callback) {
        if (typeof window.jQuery !== "undefined") {
            callback();
        } else {
            list.push(callback);
        }
    };

    this.run = function() {

        if (typeof window.jQuery !== "undefined") {
            for(var i in list) {
                try {
                    list[i]();
                } catch (ex) {
                    console.error(ex);
                }
            }
            list = [];
        }
    };

    if (window.addEventListener) {
        window.addEventListener("load", this.run, false);
    } else if (window.attachEvent) {
        window.attachEvent("onload", this.run);
    } else {
        if (window.onload && window.onload !== this.run) {
            this.push(window.onload);
        }
        window.onload = this.run;
    }
};

Using this I can define any anonymous loader over the page, before jQuery and bootstrap inclusion and stay sure that it will fire once jQuery is present:

init.push(function() {

    $('[name="date"]').datepicker({
        endDate: '0d',
        format: 'yyyy-mm-dd',
        autoclose: true
    }).on('hide', function() {
        // $.ajax
    });

    $('[name="keyword_id"]').select2();
});
Dynameter answered 23/10, 2015 at 9:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.