Run Javascript Only After Page Finishes Loading

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:

http://www.randomsnippets.com/2008/02/12/how-to-hide-and-show-your-div/

Thank you for your help.

You could use the onload attribute in the HTML BODY tag, though I’m not sure it would help much in this situation.

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.

From the Javascript Anthology book:


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 : )

Thanks for the advice.

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.