使用 .innerHTML 时 HTML 标签损坏

Posted

技术标签:

【中文标题】使用 .innerHTML 时 HTML 标签损坏【英文标题】:Broken HTML tags when using .innerHTML 【发布时间】:2013-07-10 16:01:28 【问题描述】:

作为更大脚本的一部分,我一直在尝试制作一个页面,该页面会从另一个函数中获取一段文本并将其“键入”到屏幕上:

function typeOut(page,nChar)
  var txt = document.getElementById("text");
  if (nChar<page.length)
    txt.innerhtml = txt.innerHTML + page[nChar];
    setTimeout(function () typeOut(page,nChar+1);,20);
  

这基本上按照我想要的方式工作,但是如果我传递的文本块中有任何 html 标签(如链接),这些标签会显示为纯文本而不是被解释。有什么办法可以解决这个问题并强制它正确显示 html 元素?

【问题讨论】:

【参考方案1】:

问题是您将在此过程中创建无效的 HTML,而浏览器将尝试更正。因此,显然当您添加&lt;&gt; 时,它会自动对该字符进行编码以不破坏结构。

一个正确的解决方案不会对文本的每个字符都有效,而是会逐个元素地处理 HTML 元素。 IE。每当您在源 HTML 中遇到元素时,您都会克隆该元素并将其添加到目标元素。然后你会逐个字符地处理它的文本节点。

这是我一起破解的一个解决方案(意思是,它可能可以改进很多):

function typeOut(html, target) 
    var d = document.createElement('div');
    d.innerHTML = html;
    var source = d.firstChild;
    var i = 0;

    (function process() 
        if (source) 
            if (source.nodeType === 3)  // process text node
                if (i === 0)  // create new text node
                    target = target.appendChild(document.createTextNode(''));
                    target.nodeValue = source.nodeValue.charAt(i++);
                // stop and continue to next node
                 else if (i === source.nodeValue.length)  
                    if (source.nextSibling) 
                        source = source.nextSibling;
                        target = target.parentNode;
                    
                    else 
                        source = source.parentNode.nextSibling;
                        target = target.parentNode.parentNode;
                    
                    i = 0;
                 else  // add to text node
                    target.nodeValue += source.nodeValue.charAt(i++);
                
             else if (source.nodeType === 1)  // clone element node 
                var clone = source.cloneNode();
                clone.innerHTML = '';
                target.appendChild(clone);
                if (source.firstChild) 
                    source = source.firstChild;
                    target = clone;
                 else  
                    source = source.nextSibling;
                
            
            setTimeout(process, 20);
        
    ());

DEMO

【讨论】:

太棒了。我知道我会做一些研究,在此之前它会完美运行。谢谢!【参考方案2】:

您的代码应该可以工作。此处示例:http://jsfiddle.net/hqKVe/2/

问题可能是page[nChar] 的内容有 HTML 字符转义。

最简单的解决方案是使用jQuery 的html() 函数(如果您使用jQuery)。 Canavar 在这里给出了一个很好的例子:How to decode HTML entities using jQuery?

如果您不使用 jQuery,则必须自己对字符串进行转义。在实践中,只需与此处描述的相反:Fastest method to escape HTML tags as HTML entities?

【讨论】:

您的示例没有逐个字符地添加文本。这就是造成问题的原因。请参阅:jsfiddle.net/hqKVe/3。

以上是关于使用 .innerHTML 时 HTML 标签损坏的主要内容,如果未能解决你的问题,请参考以下文章

标签的innerHTML属性和html()

使用innerhtml将脚本标签插入到html元素中[重复]

在Javascript中使用多个innerHTML分隔标签

使用 INPUT 标签的 VALUE 属性(及其值)读取 HTML 表单的 innerHTML

innerHTML innerText的使用和区别

php Xpath使用innerHTML标签获取innerHTML