JavaScript Domready

Javascript domready?

i've updated the code of DOMAssistant library it works fine with me

var domReady = (function (){
var arrDomReadyCallBacks = [] ;
function excuteDomReadyCallBacks(){
for (var i=0; i < arrDomReadyCallBacks.length; i++) {
arrDomReadyCallBacks[i]();
}
arrDomReadyCallBacks = [] ;
}

return function (callback){
arrDomReadyCallBacks.push(callback);
/* Mozilla, Chrome, Opera */
if (document.addEventListener ) {
document.addEventListener('DOMContentLoaded', excuteDomReadyCallBacks, false);
}
/* Safari, iCab, Konqueror */
if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
browserTypeSet = true ;
var DOMLoadTimer = setInterval(function () {
if (/loaded|complete/i.test(document.readyState)) {
//callback();
excuteDomReadyCallBacks();
clearInterval(DOMLoadTimer);
}
}, 10);
}
/* Other web browsers */

window.onload = excuteDomReadyCallBacks;
}
})()

What are means of domready, onload, body, head?

<head> contains all the information regarding the Page properties, CSS and JavaScript. Though CSS and JavaScript can be included in the body as well. Head will include Page's meta information, Title, base URL etc.

<body> contains the actual content of the body. Which users visiting the website actually see or interact with.

DOM is Document Object Model. It's the basic structure or you can say the skeleton of the Page on which the page stands.

domready is an event which is fired as soon as the DOM has finished loading. For eg: Suppose a page has only one image. It will wait for the image tag to be parsed. As soon as the image tag is received it will be fired. It will NOT wait for whole image to be loaded from the source.

onload is an event which is fired when complete(DOM + content) page is loaded. In the previous example in donready, onload will wait for the image to be fetched from the source and then will be fired.

What is the DOM ready event?

DOM ready means that all the HTML has been received and parsed by the browser into the DOM tree which can now be manipulated.

It occurs before the page has been fully rendered (as external resources may have not yet fully downloaded - including images, CSS, JavaScript and any other linked resources).

The actual event is called window.DOMContentLoaded.

How to check if DOM is ready without a framework?

The document.readyState property can be used to check if the document is ready. From MDN:

Values


The readyState of a document can be one of following:

  • loading – The document is still loading.
  • interactive – The document has finished loading and the document has been parsed but sub-resources such as images, stylesheets and frames are still loading.
  • complete – The document and all sub-resources have finished loading. The state indicates that the load event is about to fire.

Code example:

if(document.readyState === "complete") {
// Fully loaded!
}
else if(document.readyState === "interactive") {
// DOM ready! Images, frames, and other subresources are still downloading.
}
else {
// Loading still in progress.
// To wait for it to complete, add "DOMContentLoaded" or "load" listeners.

window.addEventListener("DOMContentLoaded", () => {
// DOM ready! Images, frames, and other subresources are still downloading.
});

window.addEventListener("load", () => {
// Fully loaded!
});
}

Vanilla JavaScript equivalent of jQuery's $.ready() - how to call a function when the page/DOM is ready for it

The simplest thing to do in the absence of a framework that does all the cross-browser compatibility for you is to just put a call to your code at the end of the body. This is faster to execute than an onload handler because this waits only for the DOM to be ready, not for all images to load. And, this works in every browser.

<!doctype html>
<html>
<head>
</head>
<body>
Your HTML here

<script>
// self executing function here
(function() {
// your page initialization code here
// the DOM will be available here

})();
</script>
</body>
</html>

For modern browsers (anything from IE9 and newer and any version of Chrome, Firefox or Safari), if you want to be able to implement a jQuery like $(document).ready() method that you can call from anywhere (without worrying about where the calling script is positioned), you can just use something like this:

function docReady(fn) {
// see if DOM is already available
if (document.readyState === "complete" || document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}

Usage:

docReady(function() {
// DOM is loaded and ready for manipulation here
});

If you need full cross browser compatibility (including old versions of IE) and you don't want to wait for window.onload, then you probably should go look at how a framework like jQuery implements its $(document).ready() method. It's fairly involved depending upon the capabilities of the browser.

To give you a little idea what jQuery does (which will work wherever the script tag is placed).

If supported, it tries the standard:

document.addEventListener('DOMContentLoaded', fn, false);

with a fallback to:

window.addEventListener('load', fn, false )

or for older versions of IE, it uses:

document.attachEvent("onreadystatechange", fn);

with a fallback to:

window.attachEvent("onload", fn);

And, there are some work-arounds in the IE code path that I don't quite follow, but it looks like it has something to do with frames.


Here is a full substitute for jQuery's .ready() written in plain javascript:

(function(funcName, baseObj) {
// The public function name defaults to window.docReady
// but you can pass in your own object and own function name and those will be used
// if you want to put them in a different namespace
funcName = funcName || "docReady";
baseObj = baseObj || window;
var readyList = [];
var readyFired = false;
var readyEventHandlersInstalled = false;

// call this when the document is ready
// this function protects itself against being called more than once
function ready() {
if (!readyFired) {
// this must be set to true before we start calling callbacks
readyFired = true;
for (var i = 0; i < readyList.length; i++) {
// if a callback here happens to add new ready handlers,
// the docReady() function will see that it already fired
// and will schedule the callback to run right after
// this event loop finishes so all handlers will still execute
// in order and no new ones will be added to the readyList
// while we are processing the list
readyList[i].fn.call(window, readyList[i].ctx);
}
// allow any closures held by these functions to free
readyList = [];
}
}

function readyStateChange() {
if ( document.readyState === "complete" ) {
ready();
}
}

// This is the one public interface
// docReady(fn, context);
// the context argument is optional - if present, it will be passed
// as an argument to the callback
baseObj[funcName] = function(callback, context) {
if (typeof callback !== "function") {
throw new TypeError("callback for docReady(fn) must be a function");
}
// if ready has already fired, then just schedule the callback
// to fire asynchronously, but right away
if (readyFired) {
setTimeout(function() {callback(context);}, 1);
return;
} else {
// add the function and context to the list
readyList.push({fn: callback, ctx: context});
}
// if document already ready to go, schedule the ready function to run
if (document.readyState === "complete") {
setTimeout(ready, 1);
} else if (!readyEventHandlersInstalled) {
// otherwise if we don't have event handlers installed, install them
if (document.addEventListener) {
// first choice is DOMContentLoaded event
document.addEventListener("DOMContentLoaded", ready, false);
// backup is window load event
window.addEventListener("load", ready, false);
} else {
// must be IE
document.attachEvent("onreadystatechange", readyStateChange);
window.attachEvent("onload", ready);
}
readyEventHandlersInstalled = true;
}
}
})("docReady", window);

The latest version of the code is shared publicly on GitHub at https://github.com/jfriend00/docReady

Usage:

// pass a function reference
docReady(fn);

// use an anonymous function
docReady(function() {
// code here
});

// pass a function reference and a context
// the context will be passed to the function as the first argument
docReady(fn, context);

// use an anonymous function with a context
docReady(function(context) {
// code here that can use the context argument that was passed to docReady
}, ctx);

This has been tested in:

IE6 and up
Firefox 3.6 and up
Chrome 14 and up
Safari 5.1 and up
Opera 11.6 and up
Multiple iOS devices
Multiple Android devices

Working implementation and test bed: http://jsfiddle.net/jfriend00/YfD3C/


Here's a summary of how it works:

  1. Create an IIFE (immediately invoked function expression) so we can have non-public state variables.
  2. Declare a public function docReady(fn, context)
  3. When docReady(fn, context) is called, check if the ready handler has already fired. If so, just schedule the newly added callback to fire right after this thread of JS finishes with setTimeout(fn, 1).
  4. If the ready handler has not already fired, then add this new callback to the list of callbacks to be called later.
  5. Check if the document is already ready. If so, execute all ready handlers.
  6. If we haven't installed event listeners yet to know when the document becomes ready, then install them now.
  7. If document.addEventListener exists, then install event handlers using .addEventListener() for both "DOMContentLoaded" and "load" events. The "load" is a backup event for safety and should not be needed.
  8. If document.addEventListener doesn't exist, then install event handlers using .attachEvent() for "onreadystatechange" and "onload" events.
  9. In the onreadystatechange event, check to see if the document.readyState === "complete" and if so, call a function to fire all the ready handlers.
  10. In all the other event handlers, call a function to fire all the ready handlers.
  11. In the function to call all the ready handlers, check a state variable to see if we've already fired. If we have, do nothing. If we haven't yet been called, then loop through the array of ready functions and call each one in the order they were added. Set a flag to indicate these have all been called so they are never executed more than once.
  12. Clear the function array so any closures they might be using can be freed.

Handlers registered with docReady() are guaranteed to be fired in the order they were registered.

If you call docReady(fn) after the document is already ready, the callback will be scheduled to execute as soon as the current thread of execution completes using setTimeout(fn, 1). This allows the calling code to always assume they are async callbacks that will be called later, even if later is as soon as the current thread of JS finishes and it preserves calling order.

Javascript DOM ready without an entire framework

It seems that the safest bet is indeed to use a javascript framework. I was able to find some small DOMready libraries - but nothing written recently or claiming to be confirmed working with the most current browser releases.

Javascript - DOM ready after loading external javascript?

Check jQuery.holdReady(). If you will try to load external js via getScript then you can easily do that.

Delay the ready event until a custom plugin has loaded:

$.holdReady( true );
$.getScript( "externalScript.js", function() {
$.holdReady( false );
});

javascript:how to write $(document).ready like event without jquery

This is the way jQuery wraps the functions you're looking for - the snippet does not need jQuery, and is cross-browser compatible. I've replaced all calls to jQuery.ready() with yourcallback - which you need to define.

What goes on in here:

  • first, the function DOMContentLoaded is defined, which will be used when the DOMContentLoaded event fires - it ensures that the callback is only called once.
  • a check if the document is already loaded - if yes, fire the callback right away
  • otherwise sniff for features (document.addEventListener / document.attachEvent) and bind the callbacks to it (different for IE and normal browsers, plus the onload callback)

Lifted from jQuery 1.4.3, functions bindReady() and DOMContentLoaded:

/*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
// Cleanup functions for the document ready method
// attached in the bindReady handler
if ( document.addEventListener ) {
DOMContentLoaded = function() {
document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
//jQuery.ready();
yourcallback();
};

} else if ( document.attachEvent ) {
DOMContentLoaded = function() {
// Make sure body exists, at least, in case IE gets a little overzealous
if ( document.readyState === "complete" ) {
document.detachEvent( "onreadystatechange", DOMContentLoaded );
//jQuery.ready();
yourcallback();
}
};
}

// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
//return setTimeout( jQuery.ready, 1 );
// ^^ you may want to call *your* function here, similarly for the other calls to jQuery.ready
setTimeout( yourcallback, 1 );
}

// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
//window.addEventListener( "load", jQuery.ready, false );
window.addEventListener( "load", yourcallback, false );
// If IE event model is used
} else if ( document.attachEvent ) {
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent("onreadystatechange", DOMContentLoaded);

// A fallback to window.onload, that will always work
window.attachEvent( "onload", yourcallback );

}

That's 51 lines of pure JavaScript code, just to register the event reliably. As far as I know, there is no easier method. Goes to show what the wrappers like jQuery are good for: they wrap the capability sniffing and ugly compatibility issues so that you can focus on something else.



Related Topics



Leave a reply



Submit