So i am reading the height of an element using .offsetHeight within a window.onload listener. This means that the html elements must have loaded. However, if i use the same code but instead of using the window.onload i use a setTimeout with a 100ms wait time, the offsetHeight is different (which appears to be the correct value). Why is this? I obviously don't want to be adding unnecessary load times onto my web pages, are there any work arounds?
P.s even when using a 50ms wait time the results are inconsistent.
Thanks in advance.
Is there an way (maybe an event?) to delay querying the height of element until all of the styles for it have been fully calculated, so that I know that it's height is calculated properly?
In my app I need to get the height of an element as soon as possible. I run that calculation soon after it's been inserted into DOM (using MutationObservers for detecing that). Still some (not all) of the results are incorrect - the height is different (higher) than what I see in the end in my browser. If I delay the calculation by 200ms using setTimeout, the results are corrent though.
Is there some cleaner solution to that, without using setTimeout? That one is a bit hacky (including the fact 200ms works in my browser doesn't mean that it'll work in all others and I can't increase it - I need to do that calculation as soon as possible).
You can use the onload event which fires after everything in the document has been completely loaded.
You can use it in your markup like this:
<body onload="doStuffAfterEverythingIsLoaded()">...</body>
or in your script:
window.addEventListener("load", doStuffAfterEverythingIsLoaded);
Hope this will help.
I need to set the height of an element based on the height of another element. Let's say that when that element is finished rendering, it's 490px tall.
If I query that other element's height at the beginning of my function inside $(document).ready(), it returns 432px.
If I query that other element's height inside a setTimeout(function, 100), it returns about 475px.
If I bump the setTimeout up to 150 or so, the element is finished rendering and I get 190. But obviously I can't count on this.
I don't want to wait for the entire page to finish loading, if possible; I want to wait only on this element.
It seems like the load event is supposed to work on arbitrary elements, but as far as I can tell that's unimplemented in browsers, or at least in Chrome.
EDIT: The element is not an image and (almost certainly) no images will ever be inside the element. It's just a <div> with some other <div>s and <p>s and things in it. The height is apparently getting queried in the middle of the CSS being applied or something. Code samples forthcoming.
EDIT 2: Here's a fiddle hacked out of my site. (Please forgive the horrid markup; I haven't cleaned up Drupal's output yet.) The fiddle doesn't exhibit the bad behavior I'm trying to correct, though, because the whole snippet gets rendered before the relevant part of the Javascript is run.
Is there a way to do this, or am I stuck with window.onload?
You can do something like this:
<img src="myImage.gif" onload="loadImage()">
You will want to use at least $(window).load() since you need to wait on additional resources like images and CSS sheets that can affect the dimensions of elements on the page.
load() can work on images as well. You should be able to get it right without needing setTimeout.
http://api.jquery.com/load-event/ contains a notice that it doesn't work reliably for images.
In a nutshell I want a callback to fire after the html has been injected and the content of that html has rendered. Reason being I need to know the height of the new content right away. Something like this:
$('div').html(tonsofstuff);
console.log( $('div').height() ); //works in Firefox, but returns 0 in Chrome
setTimeout(function(){
console.log( $('div').height() ); //works everywhere, but takes too long
},3000);
The issue is occasionally in some browsers (and always in chrome) $('div').height() fires before the new content has a height.
My fantasy:
$('div').html(tonsofstuff, function(){
console.log( $('div').height() );
});
or even
$('div').html(tonsofstuff).load(function(){
console.log( $('div').height() );
});
This is what I do:
var height = $('div').html(tonsofstuff).height();
I never had any problems with waiting for it to render.
If your "tonsofstuff" has images, the setTimeout attack is the wrong approach. You need to know when each of the images are are loaded, then do your DOM height calculations. And for that, well, you may have to introspect the html to load, find the images, and use a call to somethig like the Image Preloader Plugin. I'm not necessarily recommending it; it's fairly trivial to write your own (although there may be some gotchas with certain methods). I just know there are things like this out there that should work pretty well.
If issue occurs in chrome I assume that content you are inserting contains come images. Chrome does not calculate dimentions of the images until they are completely loaded (DOM ready is not enough). So what can usualy fix the problem is executing your rendering on window.onload event. This way you make sure images loaded and .height() / .width() will work fine. Although I realize that it's not always possible because window.onload event is fired much after then DOMContentLoaded.
Another approach is to specify image dimentions explicitly via width and height attributes of the corresponding image tag. This can work if you know the image sizes. In this case it's not necessary to perform your logic on window.onload.
I have a javascript function that manipulates the DOM when it is called (adds CSS classes, etc). This is invoked when the user changes some values in a form. When the document is first loading, I want to invoke this function to prepare the initial state (which is simpler in this case than setting up the DOM from the server side to the correct initial state).
Is it better to use window.onload to do this functionality or have a script block after the DOM elements I need to modify? For either case, why is it better?
For example:
function updateDOM(id) {
// updates the id element based on form state
}
should I invoke it via:
window.onload = function() { updateDOM("myElement"); };
or:
<div id="myElement">...</div>
<script language="javascript">
updateDOM("myElement");
</script>
The former seems to be the standard way to do it, but the latter seems to be just as good, perhaps better since it will update the element as soon as the script is hit, and as long as it is placed after the element, I don't see a problem with it.
Any thoughts? Is one version really better than the other?
The onload event is considered the proper way to do it, but if you don't mind using a javascript library, jQuery's $(document).ready() is even better.
$(document).ready(function(){
// manipulate the DOM all you want here
});
The advantages are:
Call $(document).ready() as many times as you want to register additional code to run - you can only set window.onload once.
$(document).ready() actions happen as soon as the DOM is complete - window.onload has to wait for images and such.
I hope I'm not becoming The Guy Who Suggests jQuery On Every JavaScript Question, but it really is great.
I've written lots of Javascript and window.onload is a terrible way to do it. It is brittle and waits until every asset of the page has loaded. So if one image takes forever or a resource doesn't timeout until 30 seconds, your code will not run before the user can see/manipulate the page.
Also, if another piece of Javascript decides to use window.onload = function() {}, your code will be blown away.
The proper way to run your code when the page is ready is wait for the element you need to change is ready/available. Many JS libraries have this as built-in functionality.
Check out:
http://docs.jquery.com/Events/ready#fn
http://developer.yahoo.com/yui/event/#onavailable
Definitely use onload. Keep your scripts separate from your page, or you'll go mad trying to disentangle them later.
Some JavaScript frameworks, such as mootools, give you access to a special event named "domready":
Contains the window Event 'domready', which will execute when the DOM has loaded. To ensure that DOM elements exist when the code attempting to access them is executed, they should be placed within the 'domready' event.
window.addEvent('domready', function() {
alert("The DOM is ready.");
});
window.onload on IE waits for the binary information to load also. It isn't a strict definition of "when the DOM is loaded". So there can be significant lag between when the page is perceived to be loaded and when your script gets fired. Because of this I would recommend looking into one of the plentiful JS frameworks (prototype/jQuery) to handle the heavy lifting for you.
#The Geek
I'm pretty sure that window.onload will be called again when a user hits the back button in IE, but doesn't get called again in Firefox. (Unless they changed it recently).
In Firefox, onload is called when the DOM has finished loading regardless of how you navigated to a page.
While I agree with the others about using window.onload if possible for clean code, I'm pretty sure that window.onload will be called again when a user hits the back button in IE, but doesn't get called again in Firefox. (Unless they changed it recently).
Edit: I could have that backwards.
In some cases, it's necessary to use inline script when you want your script to be evaluated when the user hits the back button from another page, back to your page.
Any corrections or additions to this answer are welcome... I'm not a javascript expert.
My take is the former becauase you can only have 1 window.onload function, while inline script blocks you have an n number.
onLoad because it is far easier to tell what code runs when the page loads up than having to read down through scads of html looking for script tags that might execute.