Javascript Global Variables Not Working as expected. Help?

18,493

Solution 1

As Adam said, the issue is that you are running javascript on the document before the document has been loaded. There are a number of ways to fix this, but the simplest is to just move your javascript code to the end of the body so the document has already been parsed and is ready before your code runs like this:

<!DOCTYPE HTML>
<html>
<head>
<title>Span to Text Box - Demo - DOM</title>
</head>

<body>
<p id="text" onClick="change()">Click me!</p>
<form onSubmit="return false;">
  <input type="hidden" id="textbox" />
  <input type="hidden" id="done" onClick="changeBack()" value="Done" />
</form>

<script type="text/javascript" language="javascript">
var textNode = document.getElementById('text');
var textValue = textNode.firstChild.nodeValue;
var textboxNode = document.getElementById('textbox');
var doneButton = document.getElementById('done');
function change()
{
   textboxNode.setAttribute('value', textValue);
   textNode.style.display = 'none';
   textboxNode.setAttribute('type','text');
   doneButton.setAttribute('type','button');
}
function changeBack()
{
   textNode.firstChild.nodeValue = textboxNode.value;
   textNode.style.display = 'block';
   textboxNode.setAttribute('type', 'hidden');
   doneButton.setAttribute('type','hidden');
}
</script>

</body>
</html>

Solution 2

The error is likely caused by grabbing DOM nodes before they're ready:

var textNode = document.getElementById('text');

This is likely returning either null or undefined since that DOM element hasn't been created yet.

Putting this script at the end of your body should solve your problem.

Or, if you'd like to use jQuery, you can do all this in

$(document).ready(function() {
    var textNode = document.getElementById('text');
}

Solution 3

Use let in place of var.

<!DOCTYPE HTML>
<html>
<head>
<title>Span to Text Box - Demo - DOM</title>
<script type="text/javascript" language="javascript">
let textNode = document.getElementById('text');
let textValue = textNode.firstChild.nodeValue;
let textboxNode = document.getElementById('textbox');
let doneButton = document.getElementById('done');
function change()
{
   textboxNode.setAttribute('value', textValue);
   textNode.style.display = 'none';
   textboxNode.setAttribute('type','text');
   doneButton.setAttribute('type','button');
}
function changeBack()
{
   textNode.firstChild.nodeValue = textboxNode.value;
   textNode.style.display = 'block';
   textboxNode.setAttribute('type', 'hidden');
   doneButton.setAttribute('type','hidden');
}
</script>
</head>

<body>
<p id="text" onClick="change()">Click me!</p>
<form onSubmit="return false;">
  <input type="hidden" id="textbox" />
  <input type="hidden" id="done" onClick="changeBack()" value="Done" />
</form>
</body>
</html>

This should work for you. Thanks.

Share:
18,493
Naeem Ul Wahhab
Author by

Naeem Ul Wahhab

Specialist in Software Engineering. Love coding in PHP/SQL, Jquery and HTML5 applications and websites.

Updated on June 14, 2022

Comments

  • Naeem Ul Wahhab
    Naeem Ul Wahhab almost 2 years

    I am new to Javascript. I am facing a problem with global variables. I can't figure out that why the global variables are not working as the code looks ok. Please Help me solve this problem. I will breifly explain the code first.I have some text on a page which changes to text field when clicked. When I define the variables inside the functions body the code starts working fine. When these variables are defined globally as in the following code, the console displays this error: the variable is not defined. Here my code:

    <!DOCTYPE HTML>
    <html>
    <head>
    <title>Span to Text Box - Demo - DOM</title>
    <script type="text/javascript" language="javascript">
    var textNode = document.getElementById('text');
    var textValue = textNode.firstChild.nodeValue;
    var textboxNode = document.getElementById('textbox');
    var doneButton = document.getElementById('done');
    function change()
    {
       textboxNode.setAttribute('value', textValue);
       textNode.style.display = 'none';
       textboxNode.setAttribute('type','text');
       doneButton.setAttribute('type','button');
    }
    function changeBack()
    {
       textNode.firstChild.nodeValue = textboxNode.value;
       textNode.style.display = 'block';
       textboxNode.setAttribute('type', 'hidden');
       doneButton.setAttribute('type','hidden');
    }
    </script>
    </head>
    
    <body>
    <p id="text" onClick="change()">Click me!</p>
    <form onSubmit="return false;">
      <input type="hidden" id="textbox" />
      <input type="hidden" id="done" onClick="changeBack()" value="Done" />
    </form>
    </body>
    </html>
    

    Please Help! Thanks in Advance.

  • Nicole
    Nicole over 12 years
    +1 because I think you are right, but while I like jQuery, I wouldn't suggest it only for an onload or especially something that can be done without an onload altogether.
  • Adam Rackis
    Adam Rackis over 12 years
    @Renesis - I just want to give OP as many options as I can. I'd hate to be the guy that just recommends jQuery for everything :)
  • Zoidberg
    Zoidberg over 12 years
    I agree with this answer. It isn't the global variable aspect, it is your timing.
  • Naeem Ul Wahhab
    Naeem Ul Wahhab over 12 years
    Adam A lot of Thanks for the Reply. I know some basics about jquerry. I will consider using jQuerry as that solution looks quite simple.
  • Naeem Ul Wahhab
    Naeem Ul Wahhab over 12 years
    jfriend00 Thanks your reply really helped me to figure out the problem. It's so nice of you guys
  • Adam Rackis
    Adam Rackis over 12 years
    @capricorn - my pleasure. jQuery is an amazing library that simplifies a lot of tedious things. But if you're just adding it to your project to fix this single issue, remember, you can also fix it by simply moving your script to the bottom of your <body>
  • Naeem Ul Wahhab
    Naeem Ul Wahhab over 12 years
    @AdamRackis hmmm actually I don't like moving the code to other than head tag in the page. Just want to know if I namespace my variables like this: if(!textNode){ textNode=var textNode = document.getElementById('text');} will it also solve such problems? and is it advisable to use this technique?
  • Adam Rackis
    Adam Rackis over 12 years
    @capricorn - no, that won't solve it. The problem is that your DOM element is not ready, so document.getElementById is returning null. To fix it you can either move the script to the bottom of the body, so it'll be run after the body is parsed, and the dom is ready, or by using the jQuery construct described above.