skip to Main Content

The second element doesn’t display the expected result. Why and how to fix?

function process(sentence,element) {
    
    const words = sentence.split(' ');
    const container = document.getElementById(element);
    let index = 0;

    container.innerHTML = '';

    for (let i = 0; i < words.length; i++) {
        //console.log(words[i]);
        container.innerHTML += words[i] + ' '; // Display the word
    }
}

process("the quick <b>fox</b> jumps",'e1');   //displayed the word 'fox' as expected in bold
process("the quick <b> fox </b> jumps",'e2'); //displayed the word 'fox' as plain text, not as expected
div{
  border:1px solid #999;
  margin: 0 0 10px 0;
  display:block;
  font-size:22px
  }
<div id="e1"></div>
<div id="e2"></div>

2

Answers


  1. In the second case, the text "fox" does not appear in bold because of the following:

    There is a moment where you have added <b> to the innerHTML property, but not the closing </b>. This would be invalid HTML, and so the tag is immediately closed. Only in the next iteration of the loop the word "fox" is added, but it now comes after the <b></b> tags. And in the iteration after that, </b> is added to innerHTML, but it has no effect, as there is no matching <b>.

    In conclusion, if you assign to innerHTML be aware that the HTML is validated and corrections will be applied to make it valid.

    Login or Signup to reply.
  2. The problem is that you’re assigning to innerHTML incrementally, one word at a time. This doesn’t work well because it reparses the innerHTML into the DOM after each assignment. If the HTML is invalid, it will fix it up then; if you have an opening tag with no closing tag, it will be closed automatically.

    In the second call, when the word is just <b>, after the assignment it becomes <b></b>; and appending </b> by itself has no effect at all. So

    process("the quick <b> fox </b> jumps",'e2');
    

    is effectively equivalent to

    process("the quick <b></b> fox  jumps",'e2');
    

    As you can see, fox is no longer between <b> and </b>, so it’s not shown in bold.

    There doesn’t seem to be any good reason for the loop that assigns to innerHTML one word at a time. Just do

    container.innerHTML = sentence;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search