Mankind1023
Mankind1023

Reputation: 7732

JavaScript code not running

I have the following code:

...<some code>...
...<elements load>...

<script type="text/javascript">

    var selected_city = document.getElementById('jform_city').value;
    var selected_province=document.getElementById('jform_province').value;

    <!-- set the onchange property for all options in provice to activate getCities() -->
    document.getElementById('jform_province').onchange = function() {
        getCities();
    }

    if(selected_province != ''){
        getCities();
    }
</script>

...<more elements load>....

<script type="text/javascript">
    alert("TEST");
    document.getElementById(selected_city).selected="1";
    </script>

It selects an option from a drop down list I have, the problem is, if I remove the alert("") it stops working for some reason, any ideas?

Upvotes: 0

Views: 102

Answers (1)

Matt
Matt

Reputation: 10564

You need to wait for the document to load before trying to use document.getElementById. The alert is slowing things down enough that, behind the alert box, the element gets loaded. Without the alert, there may well be no element for "selected_city" when the following line gets run.

Check out this StackOverflow question for more info about waiting for the page to load.

EDIT

First of all, what happens when a web browser parses the page is that it translates the HTML elements it receives into a DOM - the Document Object Model, which is the in-memory representation of the page. Only after the element is in the DOM is it possible to manipulate it, and it is not necessarily true that the elements will enter the DOM in the same order as they appear in the HTML: modern fast browsers run very asynchronously, only guaranteeing that the page will end up looking as if the whole thing was loaded synchronously. This is easy to verify: almost every browser will load text and even display it while it goes and fetches images. Only after the image is fetched does it insert it into the display, shoving / reflowing the text if it has to. The end result is the same, but the page appears to load much faster this way.

Unfortunately, this "wait for it" guarantee does not apply to Javascript (as JS itself is allowed to change the way the page loads). Therefore, simply moving the script tag to the end of the document is not the same thing as waiting for the DOM to contain the element.

You have to actually wait for the browser to call you back and tell you that the DOM has been loaded - that's the only way to really know you can manipulate the DOM. This is what window.onload is for, this callback. I can think of a couple of reasons this isn't working for you:

If you actually just plugged in verbatim window.onload = function();, you missed the point - this is meant to not be an empty function, but your function. I'd assume that you didn't just type that in, but just in case, your code should be

window.onload = function(){
    document.getElementById(selected_city).selected="1";
};

Alternatively, since window.onload=[some function] is assigning a function to be called later to one single variable, there can be only one. If you're loading some other script that also assigns window.onload, your callback can be lost.

This is why frameworks such as jquery, which has a ready function that can accept and call back any number of functions, are frontend developers' gold. Here is another StackOverflow question specifically asking about using onload.

Finally, this line:

var selected_city = document.getElementById('jform_city').value;

also requires the DOM to be loaded before it runs properly. selected_city itself could be null or undefined because #jform_city is not loaded when you're asking for its value. This in turn will cause document.getElementById(selected_city) to fail, even if that element is loaded at the time that you try to select it.

Asynchronicity is a real pain in Javascript.

Any time you need to get information from the page itself, as a rule of thumb, you must wait for the DOM to load. In practice, this means that almost all of your code (except that which does not on any way require the page to be loaded) should be in a function that gets called after the page is loaded.

Upvotes: 4

Related Questions