2009-04-28 21:51:11 8 Comments
I have a script that uses $(document).ready
, but it doesn't use anything else from jQuery. I'd like to lighten it up by removing the jQuery dependency.
How can I implement my own $(document).ready
functionality without using jQuery? I know that using window.onload
will not be the same, as window.onload
fires after all images, frames, etc. have been loaded.
Related Questions
Sponsored Content
53 Answered Questions
[SOLVED] How do I check if an element is hidden in jQuery?
- 2008-10-07 13:03:18
- Philip Morton
- 2126200 View
- 6503 Score
- 53 Answer
- Tags: javascript jquery dom visibility
13 Answered Questions
[SOLVED] jQuery document.createElement equivalent?
- 2008-11-06 12:26:31
- Rob Stevenson-Leggett
- 780013 View
- 1104 Score
- 13 Answer
- Tags: javascript jquery html dom dhtml
37 Answered Questions
[SOLVED] Is there an "exists" function for jQuery?
- 2008-08-27 19:49:41
- Jake McGraw
- 652508 View
- 2248 Score
- 37 Answer
- Tags: javascript jquery
14 Answered Questions
[SOLVED] window.onload vs $(document).ready()
- 2010-09-13 06:24:52
- Vaibhav Jain
- 688178 View
- 1059 Score
- 14 Answer
- Tags: javascript jquery javascript-events unobtrusive-javascript
56 Answered Questions
19 Answered Questions
[SOLVED] Rails 4: how to use $(document).ready() with turbo-links
- 2013-09-12 17:16:41
- emersonthis
- 153761 View
- 393 Score
- 19 Answer
- Tags: javascript jquery ruby-on-rails-4 asset-pipeline turbolinks
38 Answered Questions
[SOLVED] Setting "checked" for a checkbox with jQuery?
- 2009-01-08 22:20:24
- tpower
- 2742241 View
- 3486 Score
- 38 Answer
- Tags: javascript jquery checkbox selected checked
31 Answered Questions
[SOLVED] Add table row in jQuery
- 2008-10-04 21:33:10
- Darryl Hein
- 1359079 View
- 1994 Score
- 31 Answer
- Tags: javascript jquery html-table
11 Answered Questions
[SOLVED] jQuery/JavaScript: accessing contents of an iframe
- 2008-12-13 07:20:34
- rz.
- 564489 View
- 700 Score
- 11 Answer
- Tags: javascript jquery iframe same-origin-policy
15 Answered Questions
[SOLVED] "Thinking in AngularJS" if I have a jQuery background?
- 2013-02-21 04:09:56
- Mark Rajcok
- 776698 View
- 4526 Score
- 15 Answer
- Tags: javascript jquery angularjs design
30 comments
@tnyfst 2009-04-28 22:02:04
The ready function in
jQuery
does a number of things. Frankly, I don't see that point of replacing it unless you have amazingly small output from your website.jQuery
is a pretty tiny library, and it handles all sorts of cross-browser things you'll need later.Anyway, there's little point in posting it here, just open up
jQuery
and look at thebindReady
method.It starts by calling either
document.addEventListener("DOMContentLoaded")
ordocument.attachEvent('onreadystatechange')
depending on the event model, and goes on from there.@Timo Huovinen 2011-08-13 20:52:06
Edit:
Here is a viable replacement for jQuery ready
Taken from https://plainjs.com/javascript/events/running-code-when-the-document-is-ready-15/
As the accepted answer was very far from complete, I stitched together a "ready" function like
jQuery.ready()
based on jQuery 1.6.2 source:How to use:
I am not sure how functional this code is, but it worked fine with my superficial tests. This took quite a while, so I hope you and others can benefit from it.
PS.: I suggest compiling it.
Or you can use http://dustindiaz.com/smallest-domready-ever:
or the native function if you only need to support the new browsers (Unlike jQuery ready, this won't run if you add this after the page has loaded)
@Johnny_D 2013-10-03 12:15:01
Oh, God. I will think many times before removing jquery depedency next time.
@Frederik Krautwald 2014-10-10 18:16:03
@Johnny_D Don’t add jQuery dependency in the first place = Pain gone!
@Timo Huovinen 2014-10-11 09:29:14
@FrederikKrautwald no matter what people say, conceptually jQuery is a good thing, because the DOM API is a very bloated, verbose and inconsistent, I just wish that a lite version was available
@Frederik Krautwald 2014-10-11 23:42:05
@TimoHuovinen Alternatives: Zepto.js (9.1 kb), Snack.js (8.1 kb), $dom (2.3 kb), and 140 Medley (0.5 kb). Edit: You could also take a look at Ender.
@Timo Huovinen 2014-10-13 20:41:59
@FrederikKrautwald $dom sounds like what I would want, but not sure if it fits the bill. Zepto also looks really promising, thank you for sharing!
@Timo Huovinen 2014-10-17 10:32:56
@FrederikKrautwald also qwery is looking great
@Frederik Krautwald 2014-10-17 20:53:57
@TimoHuovinen If you haven’t looked at Ender, you should definitely take a look, enderjs.com.
@dotpush 2014-12-10 22:45:01
You may also use this code from jQuery.parts if you want the ready function exactly like jQuery without the full library.
@Timo Huovinen 2014-12-11 19:41:09
@dotpush wouldn't it be great if the entire jQuery was made up from components that do one thing each and could be used separately, all as plugins for a jQuery core that does nothing.
@dotpush 2014-12-13 17:28:57
@Timo Huovinen: Your question is really, really broad! When jQuery was created, it fitted a lot of cross browsers issues generated by browsers that are today less significant. Today, "javascript only" is easier than it was. At this time, creating a "big 20kb compressed, that contains all" was surely a good idea for so much reasons I prefer not to list them all.
@Phil 2017-05-23 14:54:53
I don't like this. If people prefer this answer, ask yourself why you want to drop jQuery in the first place. It's a bit pointless if you're just going to extract the exact same functionality with all that browser fallback bloat back in to your bundle. Isn't that the whole point of avoiding jQuery in the first place?
@Timo Huovinen 2017-05-25 21:24:52
@Phil_1984_ the answer exists to demonstrate what you just argued about, that the things that jQuery does are not that simple and provides a simple alternative.
@George Jempty 2017-10-25 01:42:59
I simply use:
And unlike
document.addEventListener("DOMContentLoaded" //etc
as in the very top answer, it works as far back as IE9 -- http://caniuse.com/#search=DOMContentLoaded only indicates as recently as IE11.For instance, go to https://netrenderer.com/index.php, choose Internet Explorer 9 from the dropdown, enter https://dexygen.github.io/blog/oct-2017/jekyll/jekyll-categories/liquid-templates/2017/10/22/how-jekyll-builds-site-categories.html and click "Render", and you will see something akin to the screenshot at the bottom of this post.
See the following Javascript code I am using in the header to manipulate the style of the Jekyll "hacker" theme to my liking -- in particular you can reference the
if (location.pathname !== rootPath)
block to see how I am inserting theHome
andBlog Home
links, which are being displayed by IE9 per the NetRenderer site.Interestingly I stumbled upon this
setTimeout
solution in 2009: Is checking for the readiness of the DOM overkill?, which probably could have been worded slightly better, as I meant by using various frameworks' more complicated approaches.@user4617883 2017-10-22 05:59:46
If you don't have to support very old browsers, here is a way to do it even when your external script is loaded with async attribute:
@Chad Grant 2009-04-28 21:59:53
There is a standards based replacement,
DOMContentLoaded
that is supported by over 98% of browsers, though not IE8:jQuery's native function is much more complicated than just window.onload, as depicted below.
@XP1 2012-02-03 12:42:22
bindReady
: github.com/jquery/jquery/blob/master/src/core.js@jfriend00 2014-12-13 07:58:14
An actual working plain javascript implementation here if someone wants code they can just drop in: stackoverflow.com/questions/9899372/…
@Jose Nobile 2015-05-22 01:13:41
jQuery DOM ready code appears to be simplified: github.com/jquery/jquery/blob/master/src/core/ready.js
@Wouter Huysentruit 2015-08-13 08:16:38
@JoseNobile because they dropped older browser support
@Con Antonakos 2015-09-18 16:26:25
I think we're all ready to move on from IE8... ;). Thanks for the link, @JoseNobile.
@phirschybar 2016-06-21 13:11:47
Seems to be a pretty safe bet. .6% use of IE8 globally: caniuse.com/#feat=domcontentloaded
@Jared Insel 2016-11-16 17:03:39
DOMContentLoaded will not work if script is loaded afterwards. JQuery document ready executes always.
@ipcjs 2017-04-18 23:22:55
bindReady
old impl:github.com/jquery/jquery/blob/…@hippietrail 2017-08-05 01:23:43
Is it also possible to use something like
onDOMContentLoaded
statically in the HTML on thehtml
orbody
tag? Or can it only be done in JavaScript? And why? (-:@carl 2017-10-22 06:41:11
what happens in IE8 if I use the DOMContentLoaded example? Does the entire javascript not work or does it just load whenever it wants?
@Jakob Sternberg 2016-12-22 21:34:17
onDocReady provides a callback when the HTML dom is ready to fully access/parse/manipulate.
onDocLoad provides a callback when everything has loaded (images etc)
@Javier Rey 2016-10-13 13:55:19
This approach is the shortest way I can think of.
The solution based on the DOMContentLoaded event only works if the script is loaded before the document, whereas the lazy check suggested here ensures the code is executed always, even in scripts loaded dynamically later on, exactly as the JQuery's document ready.
This code is compatible with all browsers (including some legacy, down to IE6 and Safari for Windows).
@Diego Perini 2014-08-05 11:04:29
The setTimeout/setInterval solutions presented here will only work in specific circumstances.
The problem shows up especially in older Internet Explorer versions up to 8.
The variables affecting the success of these setTimeout/setInterval solutions are:
the original (native Javascript) code solving this specific issue is here:
this is the code from which the jQuery team have built their implementation.
@Olemak 2016-07-07 13:46:43
Here's what I use, it's fast and covers all bases I think; works for everything except IE<9.
This seems to catch all cases:
The DOMContentLoaded event is available in IE9 and everything else, so I personally think it's OK to use this. Rewrite the arrow function declaration to a regular anonymous function if you're not transpiling your code from ES2015 to ES5.
If you want to wait until all assets are loaded, all images displayed etc then use window.onload instead.
@Pawel 2013-11-18 21:58:51
Cross-browser (old browsers too) and a simple solution:
Showing alert in jsfiddle
@Quelklef 2017-08-04 20:29:29
Except if it takes more than 30ms to load the DOM, you code won't run.
@Pawel 2017-08-05 16:08:03
@Quelklef that's setInterval not setTimeout
@Quelklef 2017-08-05 16:09:40
You're right, my bad.
@Vatsal 2016-02-26 18:38:27
It's always good to use JavaScript equivalents as compared to jQuery. One reason is one fewer library to depend on and they are much faster than the jQuery equivalents.
One fantastic reference for jQuery equivalents is http://youmightnotneedjquery.com/.
As far as your question is concerned, I took the below code from the above link :) Only caveat is it only works with Internet Explorer 9 and later.
@Manan Sheth 2016-01-12 16:35:38
In short, instead of the $(document).ready() used in jQuery, we can use a JavaScript method:
Thus, when the page is ready i.e. DOMContentLoaded only then the function function_name() will be invoked.
@Katana314 2016-01-12 16:45:08
Whenever a high-voted question appears on the front page, it's often worth checking the dates to make sure you're not responding to a very old posting. (One scenario I might respond is if over the years there is a new solution not present originally. DOMContentLoaded was definitely already mentioned though.)
@Dan 2014-11-07 07:45:18
Really, if you care about Internet Explorer 9+ only, this code would be enough to replace
jQuery.ready
:If you worry about Internet Explorer 6 and some really strange and rare browsers, this will work:
@malko 2014-07-29 13:08:04
We found a quick-and-dirty cross browser implementation of ours that may do the trick for most simple cases with a minimal implementation:
@Nabi K.A.Z. 2016-03-09 22:50:35
what's
doc.body
!?@Forestrf 2014-05-27 16:22:56
Edit of the edit of @duskwuff to support Internet Explorer 8 too. The difference is a new call to the function test of the regex and the setTimeout with an anonymous function.
Also, I set the timeout to 99.
@Matt Pileggi 2014-02-21 17:16:59
If you are loading jQuery near the bottom of BODY, but are having trouble with code that writes out jQuery(<func>) or jQuery(document).ready(<func>), check out jqShim on Github.
Rather than recreate its own document ready function, it simply holds onto the functions until jQuery is available then proceeds with jQuery as expected. The point of moving jQuery to the bottom of body is to speed up page load, and you can still accomplish it by inlining the jqShim.min.js in the head of your template.
I ended up writing this code to make moving all the scripts in WordPress to the footer, and just this shim code now sits directly in the header.
@Dustin Davis 2013-12-23 19:14:32
I use this:
Note: This probably only works with newer browsers, especially these: http://caniuse.com/#feat=domcontentloaded
@Pascalius 2014-03-29 21:04:03
IE9 and above actually
@puchu 2013-10-27 20:55:47
If you want to support Internet Explorer 7+ (no quirks, compatibility and other pain), last Chrome, last Safari, last Firefox and no iframes - this will be enough:
@Richard J. Ross III 2014-01-20 13:07:39
That most definitely isn't javascript.
@Adrian 2014-01-21 17:32:16
Looks like someone writes CoffeeScript.
@Ben 2011-09-28 11:13:41
It is worth looking in Rock Solid addEvent() and http://www.braksator.com/how-to-make-your-own-jquery.
Here is the code in case the site goes down
@Peter Mortensen 2016-04-24 11:22:40
The second link is broken.
@jkdev 2016-06-27 22:03:51
web.archive.org/web/20091229112223/http://www.braksator.com/…
@KhanSharp 2013-09-12 22:33:04
Three options:
script
is the last tag of the body, the DOM would be ready before script tag executesonreadystatechange
Source: MDN
DOMContentLoaded
Concerned about stone age browsers: Go to the jQuery source code and use the
ready
function. In that case you are not parsing+executing the whole library you're are doing only a very small part of it.@0112 2014-07-16 22:12:37
This second example is much much more elegant and succinct than the marked answers. Why was this one not marked as the correct one?
@tripleee 2014-09-16 10:14:28
Still +1 for the DOMContentLoaded thing, it did exactly what I wanted.
@Abram 2016-03-10 06:16:43
onreadystatechange did the trick for me ... needed to run some script after async jquery loading.
@Machavity 2016-10-17 14:11:00
Just as an FYI, #1 is not entirely true. It's quite possible for a script at the end of the page to load before the DOM is done. That's why listeners are superior. They listen for when the browser is done. Putting it at the end is crossing your fingers that the script load was slower than the browser can render.
@Ryan 2017-08-01 19:17:12
For DOMContentLoaded listener, make sure to inline it in <head>, and not in an async script
@ZPiDER 2017-10-17 07:50:08
this variant will also work when the document is already finished loading, please update your (imo best) answer if you can: if (document.readyState == 'complete') { init(); } else { document.onreadystatechange = function () { if (document.readyState == 'complete') { init(); } } }
@CodeFinity 2018-03-26 10:54:42
For DOM element interaction, there is also just: 'interactive' for
Document.readyState
developer.mozilla.org/en-US/docs/Web/API/Document/readyState@davefrassoni 2013-02-23 11:51:26
Just add this to the bottom of your HTML page...
Because, HTML documents are parsed by top-bottom.
@Dan 2014-11-07 07:33:00
How do you know that DOM is built when this code is executed? Including loaded and parsed CSS? The browser API DOMContentLoaded is designed for that.
@rob 2009-12-07 16:46:49
Place your
<script>/*JavaScript code*/</script>
right before the closing</body>
tag.Admittedly, this might not suit everyone's purposes since it requires changing the HTML file rather than just doing something in the JavaScript file a la
document.ready
, but still...@Boldewyn 2009-12-07 16:49:51
It seems to me that there were compatibility issues, like, since the page is not yet ready, you can't do this or that in these and those browsers. Unfortunately I cannot remember more clearly. Nonetheless +1 for a way that is close enough in 99% of all cases (and suggested by Yahoo!).
@Stijn de Witt 2011-03-11 22:12:10
Actually, putting a script element at the bottom of the page is an almost perfect solution. It works cross-browser and simulates document.ready perfect. The only disadvantage is that it's (a bit) more obtrusive than using some smart code, you will have to ask the user of the script you are creating to add an extra script fragment to call your ready or init function.
@nnnnnn 2017-10-21 03:39:26
@StijndeWitt - What do you mean about having to call an init function? A script that uses document.ready doesn't need other client code to call it, it is self-contained, and the equivalent to that where the code is included at the end of the body can also be self-contained and doesn't require other code to call it either.
@Joaquinglezsantos 2016-02-03 15:20:32
For IE9+:
@Antara Roy 2015-05-22 06:20:16
Here is the smallest code snippet to test DOM ready which works across all browsers (even IE 8):
See this answer.
@chugadie 2015-02-16 14:15:41
This question was asked quite a long time ago. For anyone just seeing this question, there is now a site called "you might not need jquery" which breaks down - by level of IE support required - all the functionality of jquery and provides some alternative, smaller libraries.
IE8 document ready script according to you might not need jquery
@Luke 2015-10-13 21:31:09
I wonder why the
'onreadystatechange'
is necessary rather thandocument.attachEvent('onload', fn);
@Jakob Sternberg 2012-08-04 18:13:42
Poor man's solution:
View Fiddle
Added this one, a bit better I guess, own scope, and non recursive
View Fiddle
@Philip Langford 2013-05-19 11:25:00
It might be worth limiting the recursions with an incrementing variable within the function.
@Alex W 2013-05-22 17:40:16
@PhilipLangford Or just put it inside of a
setInterval
and remove the recursion completely.@raveren 2013-12-09 10:02:09
does this work for anybody? I had to change
function(){ alert("loaded!")
to(function(){ alert("loaded!"))()
@Jakob Sternberg 2013-12-10 03:42:35
@Raveren , hmm you're right, i'm pretty sure i tested it when i posted it. anyways, it only became even simpler, now the function just get called, no wrapping.
@Jakob Sternberg 2014-01-20 17:09:37
I just came up with this one, it's also quite sexy: (function(){ document.readyState !== "complete" ? setTimeout(arguments.caller,11) : alert("Loaded!"); })()
@snapfractalpop 2014-02-18 20:10:38
@JakobSternberg any particular reason for choosing 11 milliseconds as the interval?
@Cuadue 2014-06-19 18:17:04
@JakobSternberg Anonymous recursion! Looks like you've invented a new Y combinator implementation in JS ;)
@dudewad 2014-07-17 21:35:50
This is not sexy. No. Sorry. Using timers/intervals to detect stuff may "work" but if you keep programming like this any bigger project worth its salt is going to nose dive. Don't hack stuff together like this. Do it right. Please. This kind of code hurts the development ecosystem because there is a better solution and you KNOW it.
@iegik 2014-07-25 13:07:32
I think this answer much closer to dustindiaz.com/smallest-domready-ever So I improved script: jsfiddle.net/iegik/PT7x9
@reid 2014-12-04 00:26:28
@dudewad ... learning from mistakes is one of the best ways to learn. Saying "This kind of code hurts the development ecosystem" is a complete fallacy. In fact, it is more likely to improve it. You can't have a "right way" without a "wrong way" :)
@dudewad 2014-12-04 18:20:12
@ReidBlomquist Yes, and this is a "wrong" way, and that's what I'm pointing out (albeit a bit adamantly, I know). You could say that by doing it wrong it is somehow "helping" the ecosystem, but the problem is that with the amount of bad code out there that people take for "good" code because they don't have the experience to know any better does NOT help the ecosystem, because then they are going to take that bad code and implement it into an actual production architectural solution. So, I guess, we'll just have to differ in opinion on this "fallacy".
@reformed 2015-01-16 03:04:12
@ReidBlomquist you have some backwards reasoning going on there
@Bryan Larsen 2015-11-05 03:30:19
@AlexW, there are other reasons why this code is suboptimal, but the original's recursion is via a trampoline, so it's not problematic.
@Max Heiber 2014-12-27 16:52:42
This cross-browser code will call a function once the DOM is ready:
Here's how it works:
domReady
calls thetoString
method of the function to get a string representation of the function you pass in and wraps it in an expression that immediately calls the function.domReady
creates a script element with the expression and appends it to thebody
of the document.body
after the DOM is ready.For example, if you do this:
domReady(function(){alert();});
, the following will appended to thebody
element:Note that this works only for user-defined functions. The following won't work:
domReady(alert);
@Whome 2013-10-03 09:12:53
This was a good https://stackoverflow.com/a/11810957/185565 poor man's solution. One comment considered a counter to bail out in case of emergency. This is my modification.
@Miere 2012-09-05 16:56:58
The jQuery answer was pretty useful to me. With a little refactory it fitted my needs well. I hope it helps anybody else.
@Ron 2013-03-19 03:44:41
on some browsers, the
removeListener
will need to be called with document as the context, ie.removeListener.call(document, ...
@mike 2012-08-17 07:33:55
How about this solution?
@Zaffy 2013-01-09 10:36:38
You could use addEventListener on window with "load". Listeners are executed one after one and dont need manually chaining.
@Mzn 2013-03-30 08:45:51
But load is different than ready. The 'load' even happens before the document is 'ready'. A ready document has its DOM loaded, a loaded window doesn't necessarily have the DOM ready. Good answer though
@Tyler Rick 2013-08-23 23:24:10
@Mzn: I think that's backwards. I think document ready happens before the window load event. "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." (api.jquery.com/load-event)
@Teoman shipahi 2014-02-19 23:08:18
this will override rest of the window.onload events on the page and would cause issues. it should add event on top of existing one.
@dotpush 2014-12-10 22:29:05
The load event can happen too late. It is painful to use it when depending on third party external js/images... A non-responsive server you don't control and everything fail. Using DOMContentLoaded is not just an optimization, it's also safer!