admin管理员组

文章数量:1134598

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>

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>

Share Improve this question edited Jan 7 at 20:41 Cris asked Jan 7 at 20:37 CrisCris 2,94325 silver badges24 bronze badges 4
  • 3 It seems you've achieved the question in the title. Do you have another question? – mykaf Commented Jan 7 at 20:38
  • 2 When you add something like <b> to the existing DOM with .innerHTML +=, the browser will immediately interpret the content you append. So appending <b> by itself results in a meaningless DOM, so the browser assumes you meant <b></b>. – Pointy Commented Jan 7 at 20:45
  • If you add the strings all at once, of course it works because the browser is interpreting well-formed markup. – Pointy Commented Jan 7 at 20:46
  • Note that it's not quite accurate to say that the browser automatically turns a lone <b> into <b></b>. It kind-of does that, but the end result is the presence of a <b> node in a complete DOM. The markup itself is not the goal; its the DOM. – Pointy Commented Jan 7 at 21:09
Add a comment  | 

2 Answers 2

Reset to default 7

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.

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;

本文标签: javascriptHow to display bold text in a ltdivgt when content is added by JSStack Overflow