0

I was playing with input[range] in html with javascript. I came up with a problem. Here is the code:-

<html>
<head>
<meta charset="utf-8">
<title>Slider and range !!</title>
<script type="text/javascript">
let div = document.getElementById('display');
  function foo(value) {

    div.innerHTML = value;
  }
</script>
<style>
input[type='range']{
  border : 5px grey solid;
  border-radius: 10px;
}
</style>
</head>
<body>
  <input id="input" type="range" min = '0' max ='100' step="10" oninput="foo(this.value)" >
  <div id="display"></div>
</body>
</html>

Here in webconsole div is shown undefined but if I declare the function as this:-

  function foo(value) {
    let div = document.getElementById('display');
    div.innerHTML = value;
  }

The code is working.Why is this working like this way?Please help
Thank you.

Anand G
  • 3,130
  • 1
  • 22
  • 28

4 Answers4

3

Let's understand the how DOM parsing works on Browser.

When we load any document/HTML on DOM/Browser, It starts document parsing. It iterated elements and creates a DOM tree. It starts from TOP, goes to the header and check for other resources and execute them one by one.

Here when you wrote

 let div = document.getElementById('display');

in simple script tag without wrapping it into any function, it executed first without getting your DOM loaded.

Which means, the parser is looking for DIV by its ID which is not present yet on the browser. Hence it is undefined. Now the question is how does it work inside the function?

Functions in JavaScripts gets executed on DOMContentLoaded. This is similar to jQuery ready(). This ensures that the DOM has been ready and each element on the browser has been traversed and is now in DOM tree.

Now, you probably thinking how it works when we put this code at the bottom of the page? like

<html>
  <head></head>
  <body>
     YOUR HTML 
  </body>
  <script type="text/javascript">
      //YOUR JS CODE
  </script>

So when we insert JS which is looking for an element in DOM at the top of the page in head tag and if there is an error in getting the JS executed (like in your case the JS is looking for DIV which is not on DOM yet) it will stop the execution of DOM unless the script resolved the error.

Hence when we place JS code at the bottom of the page, the browser has already parsed all the page element and the DOM tree is ready. Thus, any element is now accessible by JS.

Which means, if you write your above code at the bottom of the page, it will get the element without error.

Footnote:

Read more about how JavaScript works on browser https://javascript.info/onload-ondomcontentloaded

Where should I put <script> tags in HTML markup?

Hope this helps,

Thanks -AG

Anand G
  • 3,130
  • 1
  • 22
  • 28
1

check this, give the script at the bottom of the page,

means initialize the div variable, only after rendering the page

<html>

<head>
  <meta charset="utf-8">
  <title>Slider and range !!</title>
  <script type="text/javascript">
    let div;

    function onLoadFunction() {
      div = document.getElementById('display');
    }

    function foo(value) {
      div.innerHTML = value;
    }
  </script>
  <style>
    input[type='range'] {
      border: 5px grey solid;
      border-radius: 10px;
    }
  </style>
</head>

<body onLoad="onLoadFunction()">
  <input id="input" type="range" min='0' max='100' step="10" oninput="foo(this.value)">
  <div id="display"></div>
</body>


</html>
Aswin Ramesh
  • 1,654
  • 1
  • 13
  • 13
  • if give i add **onload** event in body with a function, and in that function i assign the div variable,div being declared global...will it work? – Saptarshi Sahoo Jan 29 '18 at 06:31
  • yeah it will work, but you have to make sure that you assign the value globally, means without `let` keyword, or declare the variable outside and initialize it inside `onload` function – Aswin Ramesh Jan 29 '18 at 06:33
  • @UzumakiSaptarshi I had updated my code, like my above statement, check that, – Aswin Ramesh Jan 29 '18 at 06:40
1

You try to access the display element before it is loaded. Either you will have to place your script lower in the HTML file or make it execute at the onLoad function of the document.

document.onload = function() {

    //run your code here
}
Charlie
  • 22,886
  • 11
  • 59
  • 90
  • div is difined in global scope. Does it make any difference with let or var in global scope? – Saptarshi Sahoo Jan 29 '18 at 06:44
  • You are correct. The only difference is that `let` is not added as the properties of the `window` object when defined in the global scope. Answer edited. – Charlie Jan 29 '18 at 06:53
0

Not working first approach because your trying access the DOM element which not loaded yet. let div = document.getElementById('display'); by this code you trying to access immediately. When the JS code in global scope it is parse line by line and all lines execute immediately.

But following code is working fine because here you accessing the DOM element in function scope and function only running when range value are changing in the meantime the DOM is already loaded and available to manipulate.

function foo(value) {
    let div = document.getElementById('display'); // Now `display` available, so no error
    div.innerHTML = value;
}
Hanif
  • 3,739
  • 1
  • 12
  • 18