【问题标题】:Broken HTML tags when using .innerHTML使用 .innerHTML 时 HTML 标签损坏
【发布时间】: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 元素?

【问题讨论】:

    标签: javascript html innerhtml


    【解决方案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
    猜你喜欢
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多