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
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 theinnerHTML
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 toinnerHTML
, 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.The problem is that you’re assigning to
innerHTML
incrementally, one word at a time. This doesn’t work well because it reparses theinnerHTML
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. Sois effectively equivalent to
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