将“<br>”字符串注入内部 HTML 时,HTML 未正确解释

HTML isn't interpreted correctly when injecting '<br>' strings into innerHTML

'use strict';                                     

function injectCharacters(){
  var paragraph = document.getElementById( 'paragraph' ),
      text = paragraph.innerHTML,
      ary = text.split( '' ),
      i = 1;
  
  paragraph.innerHTML = '';
  
  for ( i; i <= 52 ; i++ ){
    window.setTimeout(
      ( 
        function( i ){ 
          return function(){
            paragraph.innerHTML +=  ary[ i ];
          }
        } 
      )
      ( i ), i * 100 
    )
  }
}

injectCharacters();
* {
  margin: 0;
}
html,
body {
  overflow: hidden;
  height: 100%;
}
body {
  display: flex;
  font-family: Arial;
}
p {
  margin: auto;
}
.mtx-3d {
  transform:
    perspective( 10rem )
    matrix3D( 
      1, 0.25, 0.5, 0.0075,
      0.25, 2, 2, 0.02,
      1, 2, 3, 4,
      1, 2, 3, 0.75 
    )
}
<p id="paragraph" class="mtx-3d">
  So. Yeah I mean. <br>I've been thinking <br>A lot
</p>

在上面的代码片段中,换行符是输出中的文字。我想要显示一个实际的换行符而不是看到 <br>。我该如何解决这个简单的问题?

我怀疑这与我将每个字符分解成一个数组中的值然后将其输出回段落元素有关,但我可能是错的。

通过每次添加一个新字符,使用 innerHTML += 浏览器会将 <> 字符转换为 HTMLEntities,因此序列 <br> 将被转换到 &lt;br&gt; :

para.innerHTML += '<';
console.log(para.innerHTML);
<p id="para"></p>

要修复它,您可以每次使用 innerHTML = text.slice(0, i); 设置当前内容。

'use strict';                                     

function injectCharacters(){
  var paragraph = document.getElementById( 'paragraph' ),
      text = paragraph.innerHTML,
      i = 1;
  
  paragraph.innerHTML = '';
  
  for ( i; i <= 52 ; i++ ){
    window.setTimeout(
      ( 
        function( i ){ 
          return function(){
            paragraph.innerHTML =  text.slice(0,i);
          }
        } 
      )
      ( i ), i * 100 
    )
  }
}

injectCharacters();
* {
  margin: 0;
}
html,
body {
  overflow: hidden;
  height: 100%;
}
body {
  display: flex;
  font-family: Arial;
}
p {
  margin: auto;
}
.mtx-3d {
  transform:
    perspective( 10rem )
    matrix3D( 
      1, 0.25, 0.5, 0.0075,
      0.25, 2, 2, 0.02,
      1, 2, 3, 4,
      1, 2, 3, 0.75 
    )
}
<p id="paragraph" class="mtx-3d">
  So. Yeah I mean. <br>I've been thinking <br>A lot
</p>

如果您不想显示 <<b<br,您可以事先将其替换为一些不太可能显示的字符,并且设置时再次替换它:

'use strict';                                     

function injectCharacters(){
  var paragraph = document.getElementById( 'paragraph' ),
      text = paragraph.innerHTML.replace(/<br>/g, '\u10FF'),
      i = 1;
  
  paragraph.innerHTML = '';
  
  for ( i; i <= 52 ; i++ ){
    window.setTimeout(
      ( 
        function( i ){ 
          return function(){
            paragraph.innerHTML =  text.slice(0,i).replace(/\u10FF/g, '<br>');
          }
        } 
      )
      ( i ), i * 100 
    )
  }
}

injectCharacters();
* {
  margin: 0;
}
html,
body {
  overflow: hidden;
  height: 100%;
}
body {
  display: flex;
  font-family: Arial;
}
p {
  margin: auto;
}
.mtx-3d {
  transform:
    perspective( 10rem )
    matrix3D( 
      1, 0.25, 0.5, 0.0075,
      0.25, 2, 2, 0.02,
      1, 2, 3, 4,
      1, 2, 3, 0.75 
    )
}
<p id="paragraph" class="mtx-3d">
  So. Yeah I mean. <br>I've been thinking <br>A lot
</p>

这似乎对我有用:

'use strict';                                     

function injectCharacters() {
  var paragraph = document.getElementById('paragraph'),
      text = paragraph.innerHTML,
      i = 0;

  paragraph.innerHTML = '';

  while (i < text.length) {                                 
    var c = text.charAt(i);
    if (text.slice(i, i + 4) == '<br>') {
        c = text.slice(i, i + 5);
    }
    window.setTimeout(function( c ) { 
        return function() {
          paragraph.innerHTML += c;
        }
      }( c ), i * 100 
    ); 
    i += c.length;
  }
}

injectCharacters();

我基本上重新编写了逻辑来检查 '<br>'。 如果找到,将其附加到下一个字符。这似乎保留了 <br> html 中的元素。

您需要将 html 元素拆分成它自己的元素,这样它最终会像

["a,"b","c","<br>","d","e","f"]

例如,您可以遍历元素的每个节点,拆分所有文本节点,当它看到一个元素时,只需添加该元素的 html.

Array.from(paragraph.childNodes).forEach(function(node){
  if(node.nodeType == 3){
    ary.push( ...node.textContent.split('') );
  } else {
    ary.push( node.outerHTML );
  }
});

请注意,此示例可能仅适用于没有子元素的元素,例如带有子元素的 div。如果你的段落最终包含比 <br> 更复杂的 html,它可能需要重构。

演示

'use strict';                                     

function start(){
  var paragraph = document.getElementById( 'paragraph' ),
      ary = [];
  Array.from(paragraph.childNodes).forEach(function(node){
    if(node.nodeType == 3){
      ary.push( ...node.textContent.split('') );
    } else {
      ary.push( node.outerHTML );
    }
  });

  paragraph.innerHTML = '';
  
  for ( let i=1; i < ary.length ; i++ ){
    window.setTimeout(function(){ 
      paragraph.innerHTML +=  ary[ i ];
    }, i * 100);
  }
}

start();
* {
  margin: 0;
}
html,
body {
  overflow: hidden;
  height: 100%;
}
body {
  display: flex;
  font-family: Arial;
}
p {
  margin: auto;
}
.mtx-3d {
  transform:
    perspective( 10rem )
    matrix3D( 1, 0.25, 0.5, 0.0075, 0.25, 2, 2, 0.02, 1, 2, 3, 4, 1, 2, 3, 0.75 )
}
<p id="paragraph" class="mtx-3d">
  So. Yeah I mean. <br>I've been thinking <br>A lot
</p>