Javascript like $(document).ready() for "modern HTML5" browsers - javascript

This is most likely already a question somewhere, but I cannot find it, as EVERY single search turns up jQuery questions.
I'm looking for a proven method to bind to the document being ready, much like jQuery's $(document).ready(). However, this is for a "modern browser only" page, with very light javascript, and I'd like to avoid loading jQuery here.
Would someone kindly point me in the right direction?
Thanks!

document.addEventListener('DOMContentLoaded', function () {
/* ... */
});
The event "DOMContentLoaded" will be fired when the document has been parsed completely, that is without stylesheets* and additional images. If you need to wait for images and stylesheets, use "load" instead.
* only if the <script> is before the <link rel="stylesheet" ...>

window.onload = function() {} is a standard from the long past ago, whereas it also waits for all the images to load, it is basically a working, functional alternative for some such cases also in all old browsers. A user usually still should wait a second till he makes a responsible action.
Edit: In my case, I needed it for all the libraries being loaded prior to anything else, as they were listed fixed in the footer (jquery). At it is mine dependency to continue to work with is possible just once it is loaded. So IMHO the fact that the user has to wait is irrelevant (unless I miss something here and am available to be explained), as it's the case with any way of jQuery loading, till it's not loaded it can't be worked with it. For the sake of that point ofc any way there must be a backend check as client-side js can be "intercepted". Waiting for an entire document to load is certainly more lengthy than using it just after its inclusion, however this is for cases when you eg. can't affect the order of html scripts, eg when you use it in own 3rd party package.

Related

Make all JS wait for page load

I have alot of javascript on a page, It can't be combined.
It's bugging me with the amount of "document.wait" and so forth functions on each of them, is there a better way of doing this, or am I stuck with it?
Goog'ling has revealed nothing.
As said by others move all your scripts to the bottom of the page, right before </body>. It will solve many of your issues. But it will not tackle all the subtleties of browser-inconsistencies specially for old IE.
If you want to get a glimpse of how tricky is to provide such cross-browser implementation, take a look at the following popular question:
$(document).ready equivalent without jQuery
For instance do not lean against document.addEventListener as IE proposes its own proprietary document.attachEvent. And this is only the very first step.
The best practice is to always put script tags just before you close the body:
<script src="path/to/my/script"></script>
<!-- more scripts, etc -->
</body>
This way, everything else is definitely already loaded and no need to "wait".
See this recommendation from google.
Otherwise, you can use:
window.addEventListener('load', function() {
//your js here
});

Idiomatic Dojo that does the same thing as YAHOO.util.Event.onContentReady?

I want to start manipulating a DOM element as soon as it's available, to minimize the time that it might appear in its original state on screen. I know in YUI you'd use YAHOO.util.Event.onContentReady and I'm pretty sure you'd use bind in jQuery. I'm new Dojo, and I'm not sure: What's the "Dojo Way" to do this?
UPDATE: I specifically don't want to wait for the whole page (which is ridiculously data-heavy; the markup alone is potentially a MB or more) to load. I want to immediately start looking for the element in the DOM and start processing as soon as it's there, without waiting for ALL the markup to download, be parsed, and inserted into the DOM—that could take a relatively long time. I want to start looking at the DOM and get to work as soon as this tiny fragment is there. Given that constraint, isn't dojo.ready a poor fit? My understanding is that it waits for the entire DOM to be ready, similar to onDOMReady.
The most precise way of injecting functionality after a piece of DOM is added to the tree is to have the <script> that requires it placed directly below it in markup. It seems less sexy than something like onContentReady, but onContentReady is just a polling mechanism that may end up executing your callback around the same time as domready, anyway, long after the relevant DOM subtree is ready for scripting.
Browsers can assemble a DOM tree pretty fast. And with a polling solution such as onContentReady, you're slowing down the page assembly/render by having to execute the code that searches for the targeted element(s) every few milliseconds.
I'd stick with keeping your <script>s at the bottom of the <body> or if you must, putting the must-run-now-damnit code in a <script> after the required markup.
I am not familiar with dojo's API, so I can't answer your specific question wrt dojo if the above is not helpful.
(edited to escape the leading < in tags so they would display)
dojo.addOnLoad. There is also a newer alias dojo.ready.
note: Add on load also waits to be sure all required modules are loaded, in addition to waiting for DOM-readyness
dojo.addOnLoad() is what you want. See documentation.
Note that dojo.ready() is just an alias for that method.

How to dynamically add a Javascript function (and invoke)

Based on a click event on the page, via ajax I fetch a block of html and script, I am able to take the script element and append it to the head element, however WebKit based browsers are not treating it as script (ie. I cannot invoke a function declared in the appended script).
Using the Chrome Developer Tools I can see that my script node is indeed there, but it shows up differently then a script block that is not added dynamically, a non-dynamic script has a text child element and I cannot figure out a way to duplicate this for the dynamic script.
Any ideas or better ways to be doing this? The driving force is there is potentially a lot of html and script that would never be needed unless a user clicks on a particular tab, in which case the relevant content (and script) would be loaded. Thanks!
You could try using jQuery... it provides a method called .getScript that will load the JavaScript dynamically in the proper way. And it works fine in all well known browsers.
How about calling eval() on the content you receive from the server? Of course, you have to cut off the <script> and </script> parts.
If you're using a library like jQuery just use the built-in methods for doing this.
Otherwise you'd need to append it to the document rather than the head like this:
document.write("<scr" + "ipt type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js\"></scr" + "ipt>");
In all honesty, I have no idea why the script tag is cut like that, but a lot of examples do that so there's probably a good reason.
You'll also need to account for the fact that loading the script might take quite a while, so after you've appended this to the body you should set up a timer that checks if the script is loaded. This can be achieved with a simple typeof check on any global variable the script exports.
Or you could just do an eval() on the actual javascript body, but there might be some caveats.
Generally speaking though, I'd leave this kind of thing up to the browser cache and just load the javascript on the page that your tabs are on. Just try not to use any onload events, but rather call whatever initializers you need when the tab is displayed.

JavaScript and CSS order

I have an HTML file which is linked to CSS file and also to JavaScript file.
Is JavaScript executed first and then the CSS is applied, or vice versa ?
Is there any way to change the order ?
Thanks !
It's generally considered a good idea to import your scripts as late as possible, and your stylesheets as early as possible. If possible, in fact, you should stick all your script imports at the very end of the <body>. I find that problematic when there are components pulled into the page that want to be able to drop little script blocks that reference jQuery (for example).
If your stylesheets are first, that helps make sure the browser applies styles before showing anything to the user. Conversely, by including scripts last, you defer that potentially slow script processing until after the point where the user gets to see something on the screen.
The JavaScript gets executed when the <script> element is parsed. Some of the JS might set up event handlers to run some JS when events happen.
CSS is applied to the live DOM. Changes to the DOM get CSS applied automatically. Changes to CSS apply to the whole DOM automatically.
Yahoo's research into speeding-up page loading times should be very helpful, and they explain things much clearer than I can.
http://developer.yahoo.com/performance/rules.html

Initiate onclick faster than with document.onload

I have html-pages with links where i want to attach a function to their onclick event. One way to do it is of course:
Save
But I know this is not the best practice. So instead I wait for window.onload, loop through the links and attach the save-function to the links with rel="save". The problem with this is that it waits until the whole page has finished loading which can be several seconds after the link is displayed and clickable.
So is there another way to do this? Avoiding onclick in the html but that makes it work immediately when the link is rendered.
Internet Explorer has a handy attribute for <script> tags called defer. It's for delaying the parsing of a script until the document has finished loading. For other browsers that support it, you can use DOMContentLoaded, as someone else suggested and for browsers that don't support either you can fall back to onload.
<script type="text/javascript" defer>
//- Run this code when the DOM parsing has completed
</script>
I did a quick Google search for "DOMContentLoaded defer" and found the following page that might help:
http://tanny.ica.com/ica/tko/tkoblog.nsf/dx/domcontentloaded-event-for-browsers
In your case, you can just leave that as it is. Stick to the simplest possible thing, even if it is not the general best practice.
You could try DOMContentLoaded event instead of load. IE also gives you the defer attribute for script tags, which defers execution until the DOM is loaded. If those don't work for you, then you are stuck with the solutions you mention, as far as I know.
I don't know if this is appropriate for your solution, but you could insert script immediately below the are with the links you need altered. This script would not be wrapped in a function, allowing the browser to execute it immediately when seen. The effect is that you can run script before the full page is loaded, altering only the items that exist above the script being run. (If you reference something below the script, it will fail.)
BTW, this is almost certainly not a best practice, and some would probably label it a worst practice.
How about this?
Save
Note: This solution requires to users to have Javascript enabled. Not exactly best practice, but may be suitable for your scenario.
The ideal here would be to use the ideas of Unobtrusive Javascript.
In this way, if the Javascript isn't loaded the link would still do something. It's a link right, so it leads the user to another piece of content? - this should work without Javascript. And if the functionality attached to the links can ONLY work with Javascript you should create and insert them into the DOM with Javascript (they aren't clickable if they aren't there...).
(Otherwise how about delegating the click event to a wrapper element? Does that work before the element is complete?)
edit: Oh, and "save" sounds very much like it ought to be a button in a form rather than a link. The Unobtrusive JS stuff still applies though.

Categories

Resources