4
votes

I am new to Java script. I am practicing code.When i put my code in the head section, then i get element null, and when i put it inside body, but before element, then i also get null, but if i put it inside body, but after element then i get the element. I want to ask why i am getting null in case of the first two cases. Here is my code

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

        <script type="text/javascript" src="js/attributes.js"></script>   // null

    </head>
    <body>

        <script type="text/javascript" src="js/attributes.js"></script>  // null
        <a id="braingialink"
           onclick="return showAttributes();"
           href="http://www.braingia.org" >Steve Suehring's Web Site
        </a>

        <script type="text/javascript" src="js/attributes.js"></script>   // ok

</body>

Here is my javascript

var a1 = document.getElementById("braingialink");     //get null in first two cases
window.alert(a1.getAttribute("href"));
a1.setAttribute("href", "www.google.com");
window.alert(a1.getAttribute("href"));

function showAttributes() {

    var e = document.getElementById("braingialink");
    var elementList = "";

    for (var element in e) {

        /**
         * Sometimes, especially when first programming with JavaScript, you might not know what
         * attributes are available for a given element. But you don’t have to worry about that, because
         * of a loop that calls the getAttribute() method.
         */
        var attrib = e.getAttribute(element);
        elementList = elementList + element + ": " + attrib + "\n";

    } //end of for()

    alert(elementList);

} //end of function showAttributes

And also tell me, placing <script type="text/javascript" src="js/attributes.js"></script>

after the a element, is the same as i write script in the script tag , like

<a href="http://www.braingia.org" id="braingialink">Steve Suehring's Web Site</a>
<script type="text/javascript">
    var a1 = document.getElementById("braingialink");
    alert(a1.getAttribute("href"));
    a1.setAttribute("href","http://www.microsoft.com");
    alert(a1.getAttribute("href"));
</script>

Are both things mean to same?

Thanks

7

7 Answers

6
votes

The browser parses the document from top to bottom, and if it encounters a <script> block (whether inline script or inclusion of an external JS file) it runs that JavaScript before parsing any more of the document. If that particular code block tries to refer to any elements it can only access the ones above it in the source, i.e., the ones already parsed.

The document.getElementById() method returns null if no element is found for the id you supply, so if you try to use it to access elements below it in the source they've not yet been parsed and can't be found.

The two most common practices to deal with this are:

  1. Put all of your script at the bottom of the <body> such that when it runs all of the elements will have been parsed.

  2. Create an "onload" handler, that is, define a function that will be run as soon as the document finishes loading. You can do this from a script block in the <head> - the JavaScript that defines the onload function is run immediately, but then the function is executed later after everything has loaded.

Following is the simplest way to do option 2:

window.onload = function() {
   var x = document.getElementById("x");
   // other element manipulation here
};

There is nothing stopping you doing 1 and 2 in the same document, along with throwing some <script> blocks in the middle of the document, but most people find it neater to keep all their code in the one spot.

2
votes

see http://www.w3schools.com/js/ and http://www.w3schools.com/js/js_whereto.asp

You can place an unlimited number of scripts in your document, and you can have scripts in both the body and the head section at the same time. It is a common practice to put all functions in the head section, or at the bottom of the page. This way they are all in one place and do not interfere with page content.

1
votes

You're getting null in the head because the DOM has not loaded - your objects are nonexistent at that time. Use this:

window.onload = function () {
    // Your code
}

Oh and also take a look at the .ready() function of jQuery here. It would certainly help the headache later on.

1
votes

Normally you should put script blocks inside the head tag. You can put them in the body tag if you have a special reason, for example to make the script load later because it comes from a slow server.

The reason that you can't access the element, is that the code runs before the browser has parsed the code for the element, so the element simply doesn't exist yet.

You use the load event to run the code after the document is loaded:

window.onload = function() {

  // here you put the code that needs to access the elements

}
1
votes

You need to understand how web browsers load resources into a page. Firefox -> Firebug add-on Net tab shows the timeline of how resources are loaded. If you are using jQuery or something like it (and you aught to) - then stick your code inside $(document).ready(function() { .. } - that will ensure the page has fully loaded.

Also, it's a good practise to to include your custom js last thing before </body> tag - that way page DOM would have loaded.

Have a read if you want to understand this deeper: http://www.goodreads.com/book/show/6438581-even-faster-web-sites and http://www.goodreads.com/book/show/1681559.High_Performance_Web_Sites

0
votes

Best would be right before the closing body tag, to not disturb the page loading and rendering at all! It's also recommended by google, for example for analytics snippet and also by facebook!

0
votes

you get nulls because your script executes while the browser is still loading the page. Since the page might not yet have all elements rendered, you get nulls. you need to run the script when the page has finished loading. put your script in to the HEAD element, and invoke it on body's onload event.