5

So im just testing a basic functionality on JavaScript. Im trying to set the <li> within the <ul> but for some simple reason my li gets placed outside the ul.

var test = document.getElementById('testdiv');
var data = [1,2,3,4,5];
    
test.innerHTML += '<ul>'; 
for (var i = 0; i < data[i]; i++)
{
test.innerHTML += '<li>' + i + '=' + data[i] + '</li>';
} 
test.innerHTML += '</ul>';
.start{
    border: 1px solid #000;
}  
  
     <div class="start" id="testdiv"></div>
  

Current html outcome looks like this:

<div class="start" id="testdiv">
 <ul></ul>
 <li>0=1</li>
 <li>1=2</li>
 <li>2=3</li>
 <li>3=4</li>
 <li>4=5</li>
</div>

Expected outcome with an simple explanation would be much appreciated.

<div class="start" id="testdiv">
  <ul>
   <li>0=1</li>
   <li>1=2</li>
   <li>2=3</li>
   <li>3=4</li>
   <li>4=5</li>
  </ul>
</div>
Ylama
  • 2,449
  • 2
  • 25
  • 50
  • 1
    You're writing to the DOM, not to document file. In the DOM, you can create whole elements only, and they are placed to the DOM at once. – Teemu Jan 09 '18 at 13:23
  • 1
    Building html with innerHTML is NOT like building a string. when you just do `test.innerHTML += '
      ';` The browser is actually doing this: `test.innerHTML += '
        ';` so it is closed.
      – epascarello Jan 09 '18 at 13:28
    • thanks @epascarello i actually tested it now and realized whats happening thanks for explanation. – Ylama Jan 09 '18 at 13:30

    4 Answers4

    5

    Instead of using above approach you can use below one.

    Possible reason is browser might adding the closing tag automatically to the opened tag.

    var test = document.getElementById('testdiv');
    var data = [1,2,3,4,5];
    var ulelement = document.createElement("ul");    
    for (var i = 0; i < data[i]; i++)
    {
    ulelement.innerHTML += '<li>' + i + '=' + data[i] + '</li>';
    } 
    test.appendChild(ulelement);
    .start{
        border: 1px solid #000;
    }
    <div class="start" id="testdiv"></div>
    Lalit
    • 1,354
    • 1
    • 8
    • 13
    • nice interesting approach , thanks for the help, so the browser ads closing tags automatically? – Ylama Jan 09 '18 at 13:27
    • actually tested it and it does add the closing `tag` automatically.. so my approach is wrong but i actually got this out a book and could not understand why its not working. – Ylama Jan 09 '18 at 13:29
    5

    @MikeChristensen explains why it is bad practice to use innerHtml within for loop.

    Every time innerHTML is set, the HTML has to be parsed, a DOM constructed, and inserted into the document.

    Try to use temporary string variable instead:

    var myList = '<ul>';
    for (var i = 0; i < data[i]; i++) { 
      myList += '<li>' + i + '=' + data[i] + '</li>'; 
    } 
    myList += '</ul>';
    test.innerHTML = myList;
    
    Alexander
    • 4,420
    • 7
    • 27
    • 42
    • @Ylama , I saw additional question from you. But I don't see the message now. Do you still have a question or you solve it yourself? – Alexander Jan 09 '18 at 14:09
    • Yess @Alexander please help me understand, why if `myList` is part of the loop only gets added once? your anwser is exactly 100% correct what i want it just confuses me that the 'li' gets populated 5times and the `ul` once but they are in the same loop, hope it makes sense what im asking? – Ylama Jan 09 '18 at 14:14
    • 1
      `var myList = '
        '` sets initial accumulator value. Then the `myList` is concatenated with `
      • ...
      • ` for each element of the `data` array (see `+=` [assignment operator](https://www.w3schools.com/js/js_assignment.asp)). Finally, we append close `
      tag and insert accumulated string into HTML block. My code is same as your, but I build string at first, and then write it to HTML.
      – Alexander Jan 09 '18 at 14:27
    • Thanks @Alexander now i understand much better! – Ylama Jan 09 '18 at 14:29
    0

    Use appendChild() method instead:

    var test = document.getElementById('testdiv');
    var ul = document.createElement('UL');
    
    var data = [1,2,3,4,5];
        
    for (var i = 0; i < data[i]; i++)
    {
      var li = document.createElement('LI');
      li.innerHTML = i + '=' + data[i];
      ul.appendChild(li);
    } 
    
    test.appendChild(ul)
    .start{
        border: 1px solid #000;
    }
    <div class="start" id="testdiv"></div>
    0

    I had problem with li last element was not getting populated in my case.

    I changed my code From

    $('.ul_food_item').innerHTML = li_elem_new;
    

    To

    $('.ul_food_item').html(li_elem_new);
    

    My problem was solved.

    hardik patel
    • 221
    • 4
    • 8