2

I have very simple code

html

<div id="ball" class="ball"></div>

css

#ball{
    width: 20px;
    height: 20px;
    border-radius: 100%;
    background: #0f0;
    position: absolute;
    bottom: 150px;
    left: 350px;
}

javascript

<script type="text/javascript">
    document.getElementById('ball').style.backgroundColor="red";
</script>

I tried this code in jsfiddle and it works but why this is not working locally? I tried changing to , but I've no idea why this is not working. It's showing the error:

TypeError: document.getElementById(...) is null

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231

1 Answers1

3

As mentioned in the comment, your initialization order is messed up. You can use window.onload to fix it:

<script type="text/javascript">
    window.onload = function() {
        document.getElementById('ball').style.backgroundColor="red";
    };
</script>

Note also that you can only have one onload trigger function. Here are some ideas on how to support multiple trigger functions. The easiest, is of course, to just use JQuery's ready function.

Another way is to put the <script> tag into the body after the DOM element(s) that it depends on. This is often encouraged for performance reasons, but it tends to make things less readable.

The reason as to why <script> tags in the head are executed in sequence (instead of delaying execution until after the DOM has loaded) is: Performance. For example, you sometimes might want to start asynchronous requests before the document has finished loading. If you are not concerned about performance, it's safer to execute them "onload".

Ultimately, there are a lot of considerations to be made when placing your <script> tag. If you want to learn more, this might be a good starting point.

About the second part of your question: The reason as to why it works in JSFiddle is that, by default, it executes scripts onload. You can reproduce the bug on JSfiddle by choosing "no wrap - in head": http://jsfiddle.net/aDuwg/.

Domi
  • 22,151
  • 15
  • 92
  • 122
  • thanks. its working. so it means whatever I code in js should be within onload? – Bhojendra Rauniyar Dec 02 '13 at 07:29
  • @C-Link No, just what needs to be load first. – Yair Nevet Dec 02 '13 at 07:30
  • @C-Link I added an explanation to answer your question. – Domi Dec 02 '13 at 07:33
  • 1
    @C-Link: The only rule is that the element you are trying to access has to exist. There are multiple ways to achieve that, this is one of them. – Felix Kling Dec 02 '13 at 07:33
  • *"The reason as to why ` – Felix Kling Dec 02 '13 at 07:35
  • 1
    You can include the script tag in the body of HTML after all of your elements and it should work there too. In fact, many people recommend putting all your script tags at the bottom of the HTML document, rather than the top. – Jim Pedid Dec 02 '13 at 07:35
  • @FelixKling but why are they evaluated in that sequence? I don't think that my answer is the ultimate answer to that question, but I think it describes a common use-case. I tweaked it a bit. – Domi Dec 02 '13 at 07:38
  • 1
    @JimPedid I like your response. I added a sentence on that as well. I hope, you don't mind? – Domi Dec 02 '13 at 07:41
  • Keep in mind that Ajax didn't exist when JavaScript was developed. I believe that the decision was made because it felt natural: Why should a ` – Felix Kling Dec 02 '13 at 07:46