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);
CodePudding user response:
The documentation of jQuery has the answer to your question.
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 firesDOMContentLoaded
before the code calls.ready( handler )
, the function handler will still be executed. In contrast, aDOMContentLoaded
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.
CodePudding user response:
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 staticimport
.
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 yourscript
tag (only works forsrc
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).