简体   繁体   中英

$(document).ready equivalant in JavaScript

I try to find equivalent code for jQuery $(document).ready, and find there are some different versions:

Version 1:

function ready(fn) {
  if (document.readyState != 'loading'){
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

Version 2:

document.addEventListener('DOMContentLoaded', fn);

What is the difference? Why version 1 will check document.readyState? Also version 1 is a function, while version 2 is an executed statement. So should there be one statement for version 1:

ready(fn);

The difference is that the first one will work even if the script is executed after DOMContentLoaded has fired (see document.readyState for more), provided you add the call to ready you asked about. The second won't, because the event is only fired once, so if the script is executed after that, fn will never get called.

So how could the script be executed after the event has already fired? Basically, if it's added dynamically, not as part of the document's initial HTML. Here are a couple of examples of how that could be:

  • A script element added after the document has loaded.
  • A module loaded via dynamic import() rather than static import .

There are probably others.

Also version 1 is a function, while version 2 is an executed statement. So should there be one statement for version 1:

 ready(fn);

Yes, absolutely right.


I should note that you don't need either of those if you control how the script is included in the page. (So, you do need it in libraries, but rarely in apps/pages.) If you control how the script is included in the page, and want your code to run after the DOM has been built, here are several ways you can do that (IMHO, in order of best practice):

  • Use type="module" on the script to make it a module. Modules aren't executed until the DOM has been built (they're auto-deferred, even inline modules; see the next bullet point).
  • Use defer on your script tag (only works for src script tags referring to files, not inline scripts). Deferred scripts aren't executed until the DOM has been built.
  • Put the script tag at the end of the document, just before the closing </body> tag.

If you do any of those things, there's no need to use ready (jQuery's or the ones in your question).

The documentation of jQuery has the answer to your question.

jQuery.ready() :

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.…

So your Version 2 has the described problem. While Version 1 calls the passed function even after the document is already ready.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM