简体   繁体   中英

Cannot set property innerHTML of null on appended child (div)

Before I learn some Unity I wanted to be able to create a simple Javascript game out of my own knowledge. So, I started experimenting with a timer and it worked. Then I wanted to add a div element to my HTML document and have its text change in response to the timer. So I wrote this code:

 var counter = 0; var seconds = 0; $(document).ready(function(e) { var element = document.createElement("div"); element.id = "text2"; document.getElementById("canvas").appendChild(element); function gameActions() { document.getElementById("canvas").innerHTML = seconds; if (seconds == 1) document.getElementById("text2").innerHTML = "second"; else document.getElementById("text2").innerHTML = "seconds"; counter++; if (counter % 50 == 0) { seconds++; } } setInterval(gameActions, 20); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="canvas" class="imgcenter" style="width: 500px; height: 400px; background-color: #eeffee;"> </div> 

Basically I'm intending to change the text of the "parent" div which displays the number of seconds passed after the html page is fully loaded. But before that, I'm trying to create a div with id text2 to add it inside the div parent.This div should display the word "seconds" depending on the time (basically display "second" when the seconds variable is 1, and "seconds" when not)

Where "imgcenter" is only CSS to specify auto margin. The error is that, whenever I run this on Chrome, I get:

Uncaught TypeError: Cannot set property 'innerHTML' of null

Am I correct to assume the div is not being added? Am I missing a step in the addition? Please let me know what you think the error is, thank you

This code:

var element = document.createElement("div");
element.id = "text2";
document.getElementById("canvas").appendChild(element);

… puts the element you are trying to target inside the canvas div.

This code:

    document.getElementById("canvas").innerHTML = seconds;

destroys everything in that element and replaces it with the HTML in the seconds variable.

Am I correct to assume the div is not being added?

No. The div is added, but then you destroy it before trying to do anything with it.

In your line document.getElementById("canvas").innerHTML = seconds; you are replacing your complete innterHTML of canvas . By that your element text2 is removed again.

If you want to show the unit independently from the seconds in it's own element, you should create an element unit for example like this:

 var counter = 0; var seconds = 0; $(document).ready(function (e) { var element = document.createElement("div"); var unit = document.createElement("div"); // create a second element unit element.id = "text2"; unit.id = "unit"; // asign the id unit document.getElementById("canvas").appendChild(element); document.getElementById("canvas").appendChild(unit); function gameActions() { document.getElementById("unit").innerHTML = seconds; // replace the unit with the valuen of seconds if (seconds == 1) document.getElementById("text2").innerHTML = "second"; else document.getElementById("text2").innerHTML = "seconds"; counter++; if(counter % 50 == 0) { seconds++; } } setInterval(gameActions, 20); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="canvas" class="imgcenter" style="width: 500px; height: 400px; background-color: #eeffee;"> </div> 

You are removing the element you added when you replace the inner HTML of the canvas. It would be better if you just updated the entire contents with the entire string instead of creating a separate element. I would also wrap it in an IIFE so that the variables don't leak into the global scope.

(function () {
    var counter = 0;
    var seconds = 0;

    var canvas = document.getElementById("canvas");

    function gameActions() {
        canvas.innerHTML = seconds + " second" + (seconds > 1 ? "s" : "");

        counter++;

        if (counter % 50 == 0) {
            seconds++;
        }

    }

    $(function() {
        setInterval(gameActions, 20);
    });
})();

http://jsfiddle.net/1unn153b/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM