【问题标题】:HTML isn't interpreted correctly when injecting '<br>' strings into innerHTML将“<br>”字符串注入 innerHTML 时,HTML 未正确解释
【发布时间】:2017-09-08 02:13:59
【问题描述】:

'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>

在上面的 sn-p 中,换行符是输出中的文字。我想要显示一个实际的换行符而不是看到&lt;br&gt;。我该如何解决这个简单的问题?

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

【问题讨论】:

  • 我实际上没有看到您的代码将&lt;br&gt; 标签注入到内部 HTML 中。这应该发生在哪里?
  • @TimBiegeleisen,
    来自元素的 html
  • @TimBiegeleisen 原始段落元素中包含&lt;br&gt; 标签。我将它的innerHTML 内容拆分为一个数组,然后将其再次注入到元素中,一次一个数组值。超时后。
  • 这个问题可能是重复的,但是您是否使用调试器单步执行您的代码并检查可能作为换行符出现的字符?检查段落的第一行直到行尾。您认为&lt;br&gt; 在原始 HTML 中的位置是什么?
  • 您认为一次连接 html 1 个字符是导致问题的原因是正确的。输入时它将看到&lt;,然后将其视为该字符,而不是表示元素标记开始的标记。

标签: javascript html css innerhtml line-breaks


【解决方案1】:

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

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

要修复它,您可以每次使用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>

如果您不想显示&lt;&lt;b&lt;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>

【讨论】:

  • 伟大的洞察力。您的示例仍然无效,但我正在自己尝试您的建议。
  • @basement 哪个浏览器?
  • Chrome 但您没有更新 javaScript 以在 ex 中反映 innerHTML = text.slice(0, i);,是吗?你在哪条线上解决了这个问题。我没有看到它,并且 sn-p 不起作用。
  • @basement 是的,那里确实发生了一些奇怪的事情......已修复
  • 这很好。这很好,现在我将尝试消除瞬间出现的小于号。如果我能用这种技术解决它,我会接受。
【解决方案2】:

这似乎对我有用:

'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();

我基本上重新设计了检查逻辑 '&lt;br&gt;'。 如果找到,将其附加到下一个字符。这似乎保留了 html 中的&lt;br&gt; 元素。

【讨论】:

    【解决方案3】:

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

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

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

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

    请注意,此示例可能仅适用于没有子元素的元素,例如带有子元素的 div。如果您的段落最终包含比 &lt;br&gt; 更复杂的 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>

    【讨论】:

    • 另一个很棒的解决方案。谢谢。
    猜你喜欢
    • 2015-06-08
    • 2014-01-23
    • 1970-01-01
    • 2013-02-06
    • 2012-09-21
    • 2017-01-12
    • 2012-07-04
    • 2013-10-19
    相关资源
    最近更新 更多