使用.innerHTML时HTML标记损坏

时间:2013-07-12 07:08:11

标签: javascript html innerhtml

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

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元素?

2 个答案:

答案 0 :(得分:3)

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

正确的解决方案不会对文本的每个字符都有效,但会按元素处理HTML元素。即每当遇到源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

答案 1 :(得分:-1)

您的代码应该有效。示例: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?