I am a bit lost in the "start up" events - there are so many different events and are named differently in the DOM and in various frameworks like jQuery. What are all possible start up events? How do they differ? Can you show a simple timeline to demonstrate in which order are these events fired?
.ready()
While JavaScript provides the load event for executing code when a
page is rendered, this event does not get triggered until all assets
such as images have been completely received. In most cases, the
script can be run as soon as the DOM hierarchy has been fully
constructed. The handler passed to .ready() is guaranteed to be
executed after the DOM is ready, so this is usually the best place to
attach all other event handlers and run other jQuery code. When using
scripts that rely on the value of CSS style properties, it's important
to reference external stylesheets or embed style elements before
referencing the scripts.
In cases where code relies on loaded assets (for example, if the
dimensions of an image are required), the code should be placed in a
handler for the load event instead.
The .ready() method is generally incompatible with the attribute. If load must be used, either do not use .ready()
or use jQuery's .load() method to attach load event handlers to the
window or to more specific items, like images.
Ref: http://api.jquery.com/ready/
.load()
This method is a shortcut for .on( "load", handler ).
The load event is sent to an element when it and all sub-elements have
been completely loaded. This event can be sent to any element
associated with a URL: images, scripts, frames, iframes, and the
window object.
In general, it is not necessary to wait for all images to be fully
loaded. If code can be executed earlier, it is usually best to place
it in a handler sent to the .ready() method.
Ref: http://api.jquery.com/load-event/
GlobalEventHandlers.onload
The load event fires at the end of the document loading process. At
this point, all of the objects in the document are in the DOM, and all
the images and sub-frames have finished loading.
There are also Gecko-Specific DOM Events like DOMContentLoaded and
DOMFrameContentLoaded (which can be handled using
EventTarget.addEventListener()) which are fired after the DOM for the
page has been constructed, but do not wait for other resources to
finish loading.
Cross-browser fallback
Internet Explorer 8 supports the readystatechange event, which can be
used to detect that the DOM is ready. In earlier version of Internet
Explorer, this state can be detected by regularily trying to execute
document.documentElement.doScroll("left");, as this snippet will throw
an error until the DOM is ready.
General-purpose JS libraries such as jQuery offer cross-browser
methods to detect that the DOM is ready. There are also standalone
scripts that offer this feature : contentloaded.js (supports only one
listener) and jquery.documentReady.js (doesn't depend on jQuery,
despite its name). Ref:
https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onload
Code:
document.addEventListener("DOMContentLoaded", function (event) {
console.log("DOM fully loaded and parsed");
});
function load() {
console.log("load event detected!");
}
window.onload = load;
$(document).ready(function () {
console.log('ready');
});
$(window).load(function () {
console.log('loaded');
});
Timeline demo: http://jsfiddle.net/HgJ33/
Can be interesting to write down the different frameworks and their events:
Here is test series using jsFiddle. Same html, different frameworks, difference in ms.
Mootools
window.onload = function () {
var now = new Date().getTime() - time;
console.log(now, 'onload') // 14 ms
};
window.addEvent('load', function () {
var now = new Date().getTime() - time;
console.log(now, 'load') // 15 ms
});
window.addEvent('domready', function () {
var now = new Date().getTime() - time;
console.log(now, 'domready') // 1 ms
});
jQuery
window.onload = function () {
var now = new Date().getTime() - time;
console.log(now, 'onload') // 20 ms
};
$(document).on('DOMContentLoaded', function () {
var now = new Date().getTime() - time;
console.log(now, 'DOMContentLoaded') // 10 ms
});
$(document).on('ready', function () {
var now = new Date().getTime() - time;
console.log(now, 'ready') // 20 ms
});
Dojo Toolkit
dojo.addOnLoad(function() {
//do stuff
});
YUI
YUI().use('*',function(Y) {
Y.on("domready", function() {
//do stuff
}, Y, "The DOMContentLoaded event fired. The DOM is now safe to modify via script.");
});
Prototype
document.observe("dom:loaded", function() {
//do stuff
});
Sencha JS
Ext.onReady(function() {
//do stuff
});
In general, previosus answers are very good and full.
But one important difference between .ready() and DOMContentLoaded event exists.
Most browsers provide similar functionality in the form of a
DOMContentLoaded event. However, jQuery's .ready() method differs in
an important and useful way: If the DOM becomes ready and the browser
fires DOMContentLoaded before the code calls .ready( handler ), the
function handler will still be executed. In contrast, a
DOMContentLoaded event listener added after the event fires is never
executed.
Ref. https://api.jquery.com/ready/
As we see from this, .ready() is executed at least once in all cases.
For example, in browser console we may define
>> function sample()
{
console.log('This is sample.');
$( document ).ready(function ()
{
console.log("Ready is working in all cases.")
});
}
undefined
and in result we have
>> sample();
undefined
This is sample. debugger eval code:3:11
Ready is working in all cases. debugger eval code:7:13
>> sample();
undefined
This is sample. debugger eval code:3:11
Ready is working in all cases. debugger eval code:7:13
It is better to think from the perspective of what you want and which browsers to support.
To make manipulations in Document Object Model (DOM) you will have to make sure the HTML page is loaded over network and parsed into a tree. One way of tackling this is by writing all code at end of the HTML file which leads to processing those javascript only after parsing the HTML. The other newer standard way is to listen for the DOMReady or DOMContentLoaded event or ready event to make sure the handler is run only after DOM is ready
After DOM tree is built browser will request for images, audio, video etc. After all these resources are loaded window load event is fired ,now the page is ready to be rendered fully.
So basically you should just think if your code can be executed with the DOM tree ready, or do you need everything loaded to run your code. If the native javascript implementation of DOM ready doesnt cover all the browsers you need to support, you can go for jQuery DOMready that is the reason why its made.
Related
Today I am Playing with DOM readyState,And I find something strange in JQuery.ready(),
JQuery.ready() event occurs before DOMContentload event then i put interactive in my code
like : document.readyState === "interactive"
Then this code is load before Jquery.ready() So, I have a question , is
JQuery.ready() is equal or similar to document.readyState === "interactive?
and What Technique JQuery Applies in there .ready() Event ?
How I apply this .ready() in my pure Javascript ?
I read lots of similar post of that type but no one gives the exact solution to implement JQuery.ready() on JavaScript they all load after DOMContentload not when .ready().
Here MY Jsfiddle
when we browse something the document.readyState can be one of the 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.
JQuery.ready() is not equal or similar to document.readyState === "interactive because .redyState return a string interactive or loading browser is syncing data from server, when it done it return complete string and create a load event.
The jQuery uses the above functionality to create the doc.ready() for their library.
if you wish to run your function after loading the document, there are many ways... but one of these
function myFun(){
// All your JS code which will use in your document
console.log("Hey now I am ready to run");
}
// just call the myFun() in a eventListene function as callback function
//the myFun will run after the
document.addEventListener('DOMContentLoaded', myFun, false);
A little idea what jQuery does (which will work wherever the script tag is placed).
const ready =(fun) => {
if(document.ready == 'interactive' || document.readyState =="complete"){
// calling function
setTimeout(fun, 1);
}
// we can also implement by event listner
else {
document.addEventListener("DOMContentLoaded", fun);
}
}
ready(() => {
// This is the functin whitch pass to the ready function
console.log("I am ready.")
});
hey I know that is not good but the idea behind it is that.
A little idea what jQuery does (which will work wherever the script tag is placed).
The alternative ways are
if supported, it tries the standard:
window.addEventListener('load', fn, false )
with a fallback to:
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);
window.attachEvent("onload", fn);
the information taken from :document.ready on MDN
I have come across some code using $(window).ready() that does dome UI resizing and positioning on HTML elements. I wondering why it is used? Is there an advantage to using it this way?
Are there any advantages over $(document).ready()?
The advantage of ready over the load event is that it fires as soon as the DOM is ready, without waiting for the distance resources (mainly the images) to be loaded. Usually you just want to be sure the elements are present, so that you can bind to them, but you don't need the distance resources to be loaded.
From the documentation :
In most cases, the script can be run as soon as the DOM hierarchy has
been fully constructed
$(window).ready() and $(document).ready() are equivalent.
From the source code :
ready: function( fn ) {
// Add the callback
jQuery.ready.promise().done( fn );
return this;
},
You see that the argument isn't even used, it's just returned so that you can chain if you want. You could have done this :
$({}).ready(function(){
...
});
But you shouldn't worry and should use the shortcut :
$(function(){
// your code which needs the DOM here
});
I looked at the jQuery 1.9.0 source code, and it doesn't look like the .ready() method uses at the object it was applied to; it has document hard-coded throughout it. So all $(anything).ready(...) calls are equivalent.
Download the source code and see the definition of jquery.ready.promise, this is where most of the work of $(...).ready() is done.
The documentation makes it clear that $(window).ready() doesn't have a defined meaning:
The .ready() method can only be called on a jQuery object matching the current document, so the selector can be omitted.
Currently the object is ignored, the above allows them to change this behavior in the future, since it shouldn't impact any correctly-written code.
i am trying to get the first ready state of the DOM. the second, third, etc is not interesting me, but the first one. is there any trick to get the first ready state of DOM?
$(document).ready(function() {
// is it the first ready state?
});
There are 4 readyState possible values:
uninitialized - Has not started loading yet
loading - Is loading
interactive - Has loaded enough and the user can interact with it
complete - Fully loaded
To see it's value use this code:
document.onreadystatechange = function () {
if (document.readyState === YourChoice) {
// ...
}
}
I could not catch the uninitialized readyState. (but why should I need it?)
If you need a listener for complete load of the DOM, use:
document.addEventListener('DOMContentLoaded', YourListener);
or
document.addEventListener('load', YourListener);
or even
window.onload = YourListener;
for jquery:
$(document).on("DOMContentLoaded", function() { });
or
$(document).on("load", function() { });
or
$(window).on("load", function() { });
Ah, you're using jQuery. Have a look at the docs: There is only one ready event! I will never fire multiple times. Internally, this is even handled with a Promise, so it cannot fire multiple times.
I have code like this:
$(document).ready(function () {
$('.accessLink')
.bind('click', accessLinkClick);
$('#logoutLink')
.click(function (e) {
window.location = $(this).attr('data-href')
});
});
Functionality for each part of my site is divided into a number of small files and when the site is deployed these are mimified and joined up.
Each of these small files which number up to ten wait on $(document).ready. Can anyone tell me if there is much overhead in doing this. Splitting my code into functional areas has meant the code looks easy to maintain but I am just wondering about overhead now that I am using jQuery 1.8.1
Update:
Based on the answers I started to code like this:
$(document).ready(function () {
accessButtons(); // login, register, logout
layoutButtons();
themeButtons(); // theme switcher, sidebar, print page
});
with each function then coded as:
function accessButtons() {
$('.accessLink')
.bind('click', accessLinkClick);
$('#logoutLink')
.click(function (e) {
window.location = $(this).attr('data-href')
});
};
Here's the difference between 10 $(document).ready() calls versus one that then calls 10 initialization functions.
With the 10 calls, you get:
10 calls to $(document).
10 calls to the .ready() method.
One event listener for the DOM ready event
When the DOM ready event fires, it then cycles through an array of callbacks and calls each callback passed to .ready().
If you have one $(document).ready() that then called all 10 of your initialization functions, you would have this:
1 call to $(document).
1 call to the .ready() method.
One event listener for the DOM ready event
When the DOM ready event fires, it then calls your one ready handler.
Your ready handler then calls the 10 initialization function calls.
So, the difference is approximately the time it takes to construct 9 extra jQuery objects and make 9 extra .ready() method calls. In extreme cases this could be noticeable, but it is unlikely that you would see a difference in practice.
If the code needs to be executed in order, then they should in the same dom ready callback function, otherwise, you could divide them into different dom ready callback.
Only use the .ready() function to wrap all code that needs to be run once ALL other code is loaded and once the page is ready. If you have any libraries that can run on their own and do not need to do anything with the DOM then you shouldn't need to put them into a ready call.
Performance goes down when using many $(document).ready() calls, but it doesn't seem to be too bad, and on some browsers it doesn't seem to affect performance very much at all. The linked page has test results for several popular browsers when using $() to modify a large DOM.
Due to the performance issue, I personally create separate functions for each page. So instead of having $(document).ready() run multiple times, you just fire a function on each page. This way, i tend to generally have $(document).ready() only run twice, once for globals, then once for the particular page.
function ContactForm() {
$(function () {
// Contact form page specific stuff.
});
}
In my View (by the sounds of your question, im assuming you're using MVC), what i do is add the following:
#section scripts {
#Scripts.Render("~/bundles/ContactForm")
<script type="text/javascript">ContactForm();</script>
}
Using jQuery, I can use the following function to execute code as soon as the DOM has loaded:
$(function() {
// do stuff here
});
Or equivalently:
$(document).ready(function() {
// do stuff here
});
In trying to get a better understanding of raw javascript, I'm using this code to achieve a similar effect:
window.onload = function() {
// do stuff here
}
Is this method cross-browser compatible? Are there any better ways to achieve this functionality?
Yes it is cross-browser compatible, but onLoad waits for everything on the page to load before it fires. Internally jQuery.ready uses the DOMContentLoaded event and a few hacks to support older browsers that don't support DOMContentLoaded. Most modern browsers support DOMContentLoaded including IE starting with version 9. You can test whether a browser supports DOMContentLoaded using this page.
If you are not using a DOM library such as jQuery which has built in support for DOMContentLoaded, you could use DOMContentLoaded and then fallback to onLoad if the browser doesn't support it.
(function () { // Encapsulating our variables with a IIFE
var hasRun = false; // a flag to make sure we only fire the event once
// in browsers that support both events
var loadHandler = function (evt) {
if (!hasRun) {
hasRun = true;
console.log('loaded via ' + evt.type);
}
};
document.addEventListener('DOMContentLoaded', loadHandler, false);
window.addEventListener('load', loadHandler, false);
}());
Unless you are expecting visitors with very old browsers like IE8, you are totally safe to just use DOMContentLoaded without a backup.
document.addEventListener('DOMContentLoaded', function (evt) {
console.log('loaded via ' + evt.type);
}, false);
This is similar to what JQuery does:
window.$ = {};
$.ready = function(fn) {
if (document.readyState == "complete")
return fn();
if (window.addEventListener)
window.addEventListener("load", fn, false);
else if (window.attachEvent)
window.attachEvent("onload", fn);
else
window.onload = fn;
}
And to use it:
$.ready(function() {
// code here...
});
The window onload method is cross-browser compatible, but there is a better alternative.
The jQuery ready event fires when the DOM is ready.
The window onload event fires when all data is downloaded.
So, let's say you have lots of images (or one BIG one) on your page. The html file will finish downloading and be ready for manipulation long before the images are done downloading. So jQuery's ready event shoots and you can start doing great JavaScript stuff while all those pretty pics download.
That's one of the reasons it's a good idea to use a js library.
When there aren't that many images then the difference is negligible. Though, you can only set ONE method at a time on the onload event. You can, however, set jQuery's ready event multiple times and each method will get called sequentially.
Cross-browser compatibility would have to depend on how you define the term "browser". Like for instance if it's a text based browser, then it might not be what you're looking for.
To answer your question, it will be cross-browser compatible if that particular browser warrants window.onload feature.
As a general guide, we usually use libraries that are tested so that we allow the libraries to take care of such "cross-browser" compatibility and we deal with the actual application logic.
Hope it helps!