0

I am trying to remove dependence on jQuery. I have stolen a couple of functions I needed from underscore.js, but still need my code to run after the DOM is loaded in the same way as jQuery

Original

$(function(){
  // all my code
})

Desired

var afterload = function(content){
    // what goes here..?
}

afterload(function(){
    // my code that should run after the DOM is loaded
})
Billy Moon
  • 52,018
  • 22
  • 123
  • 222
  • If you look at the jQuery source, it's a lot harder than you'd think to detect document ready... – Interrobang Feb 23 '12 at 07:13
  • I think this might help you http://stackoverflow.com/questions/799981/document-ready-equivalent-without-jquery – Tx3 Feb 23 '12 at 07:14
  • As well as [this](http://stackoverflow.com/questions/1206937/javascript-domready). There are *several* questions on this already. – Purag Feb 23 '12 at 07:15

2 Answers2

1

There is a nice solution from https://github.com/freelancephp/DOMReady,

Here is a script

/**
 * DOMReady
 *
 * @fileOverview
 *    Cross browser object to attach functions that will be called
 *    immediatly when the DOM is ready.
 *    Released under MIT license.
 * @version 2.0.0
 * @author Victor Villaverde Laan
 * @link http://www.freelancephp.net/domready-javascript-object-cross-browser/
 * @link https://github.com/freelancephp/DOMReady
 */

/**
 * @namespace DOMReady
 */
var DOMReady = (function () {

    // Private vars
    var fns = [],
        isReady = false,
        errorHandler = null,
        run = function ( fn, args ) {
            try {
                // call function
                fn.apply( this, args || [] );
            } catch( err ) {
                // error occured while executing function
                if ( errorHandler )
                    errorHandler.call( this, err );
            }
        },
        ready = function () {
            isReady = true;

            // call all registered functions
            for ( var x = 0; x < fns.length; x++ )
                run( fns[x].fn, fns[x].args || [] );

            // clear handlers
            fns = [];
        };

    /**
     * Set error handler
     * @static
     * @param {Function} fn
     * @return {DOMReady} For chaining
     */
    this.setOnError = function ( fn ) {
        errorHandler = fn;

        // return this for chaining
        return this;
    };

    /**
     * Add code or function to execute when the DOM is ready
     * @static
     * @param {Function} fn
     * @param {Array} args Arguments will be passed on when calling function
     * @return {DOMReady} For chaining
     */
    this.add = function ( fn, args ) {
        // call imediately when DOM is already ready
        if ( isReady ) {
            run( fn, args );
        } else {
            // add to the list
            fns[fns.length] = {
                fn: fn,
                args: args
            };
        }

        // return this for chaining
        return this;
    };

    // for all browsers except IE
    if ( window.addEventListener ) {
        document.addEventListener( 'DOMContentLoaded', function(){ ready(); }, false );
    } else {
        // for IE
        // code taken from http://ajaxian.com/archives/iecontentloaded-yet-another-domcontentloaded
        (function(){
            // check IE's proprietary DOM members
            if ( ! document.uniqueID && document.expando ) return;

            // you can create any tagName, even customTag like <document :ready />
            var tempNode = document.createElement( 'document:ready' );

            try {
                // see if it throws errors until after ondocumentready
                tempNode.doScroll( 'left' );

                // call ready
                ready();
            } catch ( err ) {
                setTimeout( arguments.callee, 0 );
            }
        })();
    }

    return this;

})();

and you can use like this

DOMReady.add(function (){
    alert( 'DOM is ready!' );
});
arunes
  • 3,329
  • 2
  • 19
  • 31
0

I will leave my question here, because I asked after searching stack overflow for answers, but searched the wring terms I guess. I hope other people will find this answer useful.

Initially, I was intending a functionally equivalent to jQuery solution, but without the jQuery dependance. Turns out that is very large and complex...

https://stackoverflow.com/a/7053197/665261

I then decided I wanted a concise solution, because the reason for removing jQuery dependence was to make my code load faster on low spec devices.

I am only targeting Android mobile devices, I ended up using this:

function afterload(content){
  /in/.test(document.readyState)
  ? setTimeout(function(){ afterload(content) }, 9)
  : content()
}

It should work on desktop browsers too, apparently tested on all major ones. Details and a fix for FF<3.6 can be found here: http://dustindiaz.com/smallest-domready-ever

Community
  • 1
  • 1
Billy Moon
  • 52,018
  • 22
  • 123
  • 222