appendChild is not working

0

I'm trying to pass the array elements with for (of) to the html elements I created by js. The problem is that when I try to put the created in the js inside, using appendChild, the error code. Home This is the javascript:

var listElement = document.querySelector('#app ul');
var inputElement = document.querySelector('#app input');
var buttonElement = document.querySelector('#app button');

var todos = [
    'Fazer café',
    'Estudar Javascript',
    'Lavar a Louça'
];

function renderTodos(){

for(todo of todos){
    var todoElement = document.createElement('li');
    var todoText = document.createTextNode(todo);

    todoElement.appendChild(todoText);
    listElement.appendChild(todoElement);
   }
}

renderTodos();

This is the html;

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content Language" content="pt-br">
<title>Parte 3</title>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
    <div id="app">
        <ul>    

       </ul>
       <input type="text" placeholder="Digite um To do">
       <button>Adicionar</button>
   </div>
</body>
</html>

Error occurred:

  

script.js: 18 Uncaught TypeError: Can not read property 'appendChild' of   null at renderAll (script.js: 18) at script.js: 22

    
asked by anonymous 19.07.2018 / 19:43

1 answer

1

It is the order of its execution, you have to use either DOMContentLoaded or the defer attribute in the <script> tag, this is because you are running the script before the elements in the body have been downloaded or rendered. p>

  

Enjoy and read this:

     

You can use DOMContentLoaded to check if the DOM has already loaded:

var listElement = document.querySelector('#app ul');
var inputElement = document.querySelector('#app input');
var buttonElement = document.querySelector('#app button');

var todos = [
    'Fazer café',
    'Estudar Javascript',
    'Lavar a Louça'
];

function renderTodos(){

for(todo of todos){
    var todoElement = document.createElement('li');
    var todoText = document.createTextNode(todo);

    todoElement.appendChild(todoText);
    listElement.appendChild(todoElement);
   }
}

document.addEventListener("DOMContentLoaded", renderTodos);

Or use defer to run the script only after the DOM is ready:

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

Another way would be to simply take the script from the head and put it at the end of the body, like this:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content Language" content="pt-br">
<title>Parte 3</title>
</head>
<body>
    <div id="app">
        <ul>    

       </ul>
       <input type="text" placeholder="Digite um To do">
       <button>Adicionar</button>
   </div>
   <script type="text/javascript" src="script.js"></script>
</body>
</html>
  

It is not necessary to use defer at the same time as DOMContentLoaded , although both have a small difference in the time / time they will execute, but still both will be after the DOM is accessible as querySeletor getElementById , etc.

    
19.07.2018 / 20:44