0

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

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

4

2 回答 2

3

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

一个适当的解决方案不会对文本的每个字符都有效,而是会逐个元素地处理 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);
        }
    }());
}

演示

于 2013-07-12T07:53:59.517 回答
-1

您的代码应该可以工作。这里的例子:http: //jsfiddle.net/hqKVe/2/

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

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

如果您不使用 jQuery,则必须自己对字符串进行转义。在实践中,只需与此处描述的相反:将 HTML 标记转义为 HTML 实体的最快方法?

于 2013-07-12T07:37:30.847 回答