Why does .offsetHeight take so long to load - javascript

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.

Related

How do I know the columnizing is done?

I'm using css property -column-width (and of course -moz-column-width and -webkit-column-width) to columnize the content on a webpage. The problem is when there are too much content, the proccess of columnizing is kind of slow, and can take seconds. I was told to put a spinner to alert user that the page is not ready yet, and the spinner also should block UI. But I can't find appropriate event to disable spinner. The $(document).ready() is too early. Any ideas?
If $(document).ready() is too early, you could use $(window).load(...). That's really late in the process, but I can't think of anything interim.
If there's anything you can check the placement of, you could start polling as of $(document).ready() and wait for the placement to match what you expect or stop changing or some such. Polling every 10ms or so won't have any appreciable impact, and may let you get rid of the spinner earlier than the load event.

Safely query size of element soon after inserting it to DOM

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.

How can I run a function as soon as an element has finished rendering?

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.

jquery .ready and height of element

Might seem like a trivial question but I've run into an issue while using jQuery. When I try and get the height for an element within a .ready I am always given zero.
$(function() {
$('#my-elem').height() // Always gives me zero.
});
If I put code in a delay with setTimeout() around the height check (say of .5s) then the height is correctly reported back to me. I'm guessing that this is because the styles haven't had a chance to be applied yet?
The only solution I've found to this problem is to use an interval to poll the height of the element until it becomes non-zero but this seems overkill to me. Is there a better way?
The document.ready event signals that the HTML DOM is ready for accessing via Javascript, but that doesn't mean that the elements have already rendered.
In fact, that's the whole shebang behind ready: it's a means for you to start manipulating your document's HTML DOM without having to wait for the page to finish loading. It's safe to assume that at document.ready, your elements are not yet displayed on the page.
Now, that comes with a caveat: if the elements haven't rendered yet, how can the browser / Javascript know what its resolving height is? .height() may give zero at document.ready because of this. It's probably best to wait until load instead of ready when it comes to pulling box dimensions from the layout.

Should I use window.onload or script block?

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.

Categories