This article describes how to learn the ready method in the JavaScript jQuery library, including the short Writing Method of ready, rallycool. If you need it, you can refer to jQuery in many ways, let's start with jQuery's ready function today. The code in this example comes from the jQuery script library.
If you have used jQuery, you must have used the ready function to register the functions that can be executed after the page is ready.
The question is, when will our page be ready?
Onload event
The most basic processing method is the onload event of the page. When processing this event, we can use multiple methods, that is, you can use HTML to directly write it in the start tag of the body element, you can also use the event registration method, which can be divided into the DOM0 method and the DOM2 method. Take into account the compatibility of the browser, write it out in DOM2 mode, as shown below.
if (document.addEventListener) { // A fallback to window.onload, that will always work window.addEventListener("load", jQuery.ready, false); // If IE event model is used} else { // A fallback to window.onload, that will always work window.attachEvent("onload", jQuery.ready);}
DOMContentLoaded event
However, the onload event is triggered only when all page elements are loaded, including images on the page. If there are a large number of images on the webpage, the effect can be imagined. Users may have started to operate the page when they did not see the image. At this time, our page has not been initialized, it's not too late to register the event!
In addition to the well-known onload event, which is similar to the onload event in DOM, we can also consider the DOMContentLoaded event, which is supported by a standard browser, this event will be triggered after all DOM Parsing is complete.
In this way, we can also register the processing of this event for standard-based browsers. In this way, we may capture events that have been loaded earlier.
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);}
Onreadystatechange event
What if the browser is not standard?
If the browser has a document. onreadystatechange event, when this event is triggered, if document. readyState = complete, it can be considered that the DOM tree has been loaded.
However, this event is not reliable. For example, when an image exists in the page, it may be triggered only after the onload event. In other words, it can only be correctly executed as an alternative when the page does not contain binary resources or is very small or cached.
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); // If IE event model is used} else { // 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", jQuery.ready);}
What is the DOMContentLoaded function? In the end, you still need to call the jQuery. ready function.
DOMContentLoaded = function() { if ( document.addEventListener ) { document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); jQuery.ready(); } else if ( document.readyState === "complete" ) { // we're here because readyState === "complete" in oldIE // which is good enough for us to call the dom ready! document.detachEvent( "onreadystatechange", DOMContentLoaded ); jQuery.ready(); }}
DoScroll Detection
MSDN's method of JScript is unremarkable. When the page DOM is not loaded, an exception occurs when the doScroll method is called. If no exception occurs, the page DOM is loaded!
In 2007, Diego Perini reported a method to check whether IE is loaded and called using the doScroll method. For more information, see here.
The principle is that when IE is in a non-iframe, it is only possible to continuously determine whether the DOM has been loaded by executing doScroll. In this example, we try to execute doScroll every 50 milliseconds. Note that when the page is not loaded, calling doScroll will cause an exception, so try-catch is used to catch the exception.
(function doScrollCheck() { if (!jQuery.isReady) { try { // Use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ top.doScroll("left"); } catch (e) { return setTimeout(doScrollCheck, 50); } // and execute any waiting functions jQuery.ready(); }})();
Document. readyState status
If it is too late for us to register the ready function and the page has been loaded before we register our own ready function, we do not need to check the above layers, you can check the readyState of the current page. If it is already complete, you can directly execute the ready function we are about to register. However, ChrisS reported a very special error. We need to delay the execution.
SetTimeout is often used as a timer on a web page. It allows you to specify a millisecond value as the interval for execution. When the started program needs to run in a very short period of time, we will specify a small amount of time for her, or if it needs to be executed immediately, we even set the number of milliseconds to 0, but in fact, setTimeout has a minimum execution time. When the specified time is less than this time, the browser uses the minimum allowed time as the setTimeout interval. That is to say, even if we set the number of milliseconds of setTimeout to 0, the called program is not started immediately.
What is the minimum interval? This is related to browsers and operating systems. Mentioned in John Resig's new book "The Secret of Javascript ninja"
Browsers all have a 10 ms minimum delay on OSX and a (approximately) 15 ms delay on Windows. (The minimum interval on an apple machine is 10 milliseconds, and the minimum interval on a Windows system is about 15 milliseconds)
In addition, the introduction to setTimeout in MDC also mentions that the minimum interval (DOM_MIN_TIMEOUT_VALUE) defined in Firefox is 10 milliseconds, and the minimum interval defined in HTML5 is 4 milliseconds. Since the rules are written in this way, it seems that using setTimeout can no longer shorten the minimum interval.
In this way, by setting it to 1, we can run the program after the minimum time interval supported by the browser.
// Catch cases where $ (document ). ready () is called after the browser event has already occurred. // we once tried to use readyState "interactive" here, but it caused issues like the one // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15if (document. readyState = "complete") {// after a delay of 1 ms, run the ready function setTimeout (jQuery. ready, 1 );}
Complete code
The complete code in jQuery is as follows. Located in line #842 of jQuery 1.8.3 source code.
jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); // Catch cases where $(document).ready() is called after the browser event has already occurred. // we once tried to use readyState "interactive" here, but it caused issues like the one // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready setTimeout( jQuery.ready, 1 ); // Standards-based browsers support DOMContentLoaded } else 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 ); // If IE event model is used } else { // 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", jQuery.ready ); // If IE and not a frame // continually check to see if the document is ready var top = false; try { top = window.frameElement == null && document.documentElement; } catch(e) {} if ( top && top.doScroll ) { (function doScrollCheck() { if ( !jQuery.isReady ) { try { // Use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ top.doScroll("left"); } catch(e) { return setTimeout( doScrollCheck, 50 ); } // and execute any waiting functions jQuery.ready(); } })(); } } } return readyList.promise( obj );};
So who will call it? Of course, when we call the ready function, we need to register the processing to determine whether the page is fully loaded. This code is located in line #244 of the Code in 1.8.3, as follows:
ready: function( fn ) { // Add the callback jQuery.ready.promise().done( fn ); return this;}
After referencing the jQuery script library on the page, the jQuery initialization function is executed and the ready function is created in the initialization function. Before using the ready function to register events for processing, jQuery registers the page detection code. In this way. After the page is fully loaded, the registered function is called.
Short jQuery Ready Method
When writing jQuery code, you generally need to write a Ready method to ensure that the DOM has been loaded and then execute the corresponding jQuery code. The Ready method is generally written as follows:
$ (Document). ready (function () {// start from here });
However, when reading jQuery code written by others, the following statements are often displayed:
$ (Function () {// start from here });
Although the second writing method is much shorter, it is equivalent to the first writing method in functionality. If you don't believe it, you can check that jQuery's source code contains the following code snippets:
// HANDLE: $(function)// Shortcut for document ready if ( jQuery.isFunction( selector ) ) { return rootjQuery.ready( selector );}
If the parameter in the input selector is a function, a rootjQuery is automatically returned. ready (selector), while rootjQuery is a reference of jQuery (document), so it is equivalent to calling jQuery (document ). ready () method, and the previous anonymous method is passed in for execution.
Although this short writing method reduces the amount of code, it is slightly less readable, so I personally prefer the first writing method, especially in team development, just to make it clear.