I’ve been searching the internet for an hour and came and searched Sitepoint here but I still haven’t found an answer. I have a problem with some JS code and it is because the body.onload triggers before the page has finished loading.
function toggle2(showHideDiv, switchTextDiv)
{
var ele = document.getElementById(showHideDiv);
var text = document.getElementById(switchTextDiv);
if(ele.style.display == "block")
{
alert('style.display = ' + ele.style.display); // Test code
ele.style.display = "none";
text.innerHTML = "Show Content";
}
else
{
alert('style.display = ' + ele.style.display);
ele.style.display = "block";
text.innerHTML = "Hide Content"; // Test code
}
}
I am using a link to hide or show a DIV when clicked as appropriate. The initial display is set as block in the CSS because I don’t want to hide the content from those without JS enabled. But since it is messy, I want to hide it if possible until someone chooses to see it.
Calling the toggle2 function using window.onload in the bottom of an external js file placed near the bottom of the page reveals in the alert() statement that there is no value to style.display. The style is set to block in the CSS file.
However, when I click on the link to toggle it after the page has completely loaded, the alert box displays “block” or “none”, whichever the case may be. So I know the code works. The problem is that it is being triggered before the DIV element has a style assigned to it.
I cannot place the call to the external JS file any lower than it is due to the way my templates are set up. I tried it inline, too, and had the same problem.
Is there any way to call toggle2 after the page has finished loading and the elements have style values assigned to them?
Right now I suppose I can work around it by calling a different function to explicitly hide everything setting display to none. But I would prefer to find a more elegant solution if possible.
To give credit where it is due, I got the example from this site:
I have a problem with some JS code and it is because the body.onload triggers before the page has finished loading.
I think this is because your scripts are external and sitting in the <head>, right?
If it’s just one script, you could use something like
window.onload=function(){
one function();
another();
and another();
}
But that only works if there is only One Script to Rule Us All (or, only the last script waiting for window load would run). Otherwise, you’ll want an event listener to listen until it sees (hears? lawlz) the page is loaded and then calls the external scripts.
function addLoadListener(fn) {
//mozilla and friends
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('load', fn, false);
}
//opera
else if (typeof document.addEventListener != 'undefined') {
document.addEventListener('load', fn, false);
}
//innernetz exploder
else if (typeof window.attachEvent != 'undefined') {
window.attachEvent('onload', fn);
}
//the rest is pretty much for browsers that I doubt your
//CSS or anything else still supports like IE/Mac
else {
var oldfn = window.onload;
if (typeof window.onload != 'function') {
window.onload = fn;
}
else {
window.onload = function() {
oldfn();
fn();
};
}
}
}
Once that function is made, you can launch your other functions with it
addLoadListener (one function);
addLoadListener (another…);
etc
As far as I can tell, it was a “bug” on Mozilla’s part due to the specs not saying what element you actually use for the document, so Opera did document like it should and Mozilla did window, and Webkit etc followed Mozilla. Now Mozilla’s trying to get the specs changed in their favour which might mean Opera will later switch to window. Either that or I’m listening to too much Opera propaganda : )
I read elsewhere that window.onload triggers before the page fully renders in Firefox. That’s got to be why I had problems.
My solution was to explicitly hide everything using javascript be setting the style.display = ‘block’. It isn’t as elegant as I wanted, but it does work.
For the type of processing you are trying to do the JavaScript is best placed immediately before the </body> tag. The JavaScript can then run as soon as the HTML finishes loading without needing an event handler at all.