javascript - 逐个字母地显示文本,但保留 html 格式

标签 javascript html

我需要我的文本保留一些 html 格式标记,例如更改文本的颜色以及显示文本中放置的一些图形图标。我的代码从现有隐藏段落中获取文本,清空该段落,取消隐藏它,然后逐个字母地显示它,如下所示。

        var NextHighlight = HighlightsTop.find('.newhidden').first().closest('p'); // Find the paragraph.
        // Put the text from this highlight paragraph into a variable and remove it from the paragraph, so that we can put it back letter-by-letter below.
        var HighlightText = NextHighlight.html();
        NextHighlight.html("");
        NextHighlight.removeClass('newhidden');

        // Add the text back in, letter by letter.
        showText(NextHighlight, HighlightText, 0, 5);    

....

    // The letter-by-letter function.
    var showText = function (target, message, index, interval) {    
    if (index < message.length) { 
        $(target).append(message[index++]); 
        setTimeout(function () { showText(target, message, index, interval); }, interval); 
        } 
    }

问题是 html 标签现在只显示为行中的直接文本。如果我在元素中将“html”更改为“text”,它不会显示标签,但我也不会得到格式。

编辑 - 更新如下....

使用下面的答案更新后,我的代码现在看起来像这样。我应该指出,当用户点击按钮时会发生这种情况,因此我从按钮单击开始添加代码。也许在某个地方有一个我看不到的错误,因为当我现在单击按钮时,我什么也得不到。我在控制台中也没有看到任何错误,想知道我是否错过了 ;某处...

$(document).on('click', '.highlight_button',
    function () {
        var MatchReportTop = $(this).closest('.match_div'); 
        var HighlightsTop = $(this).closest('.highlights');
        var NextHighlight = $('.newhidden').first().closest('p'), HighlightTextNodes = [];

        // recursively get the text nodes
        (function recursiveGetTextNodes(node) {
          if(node.nodeType === 3) {
            // we're a text node? great, store it.  We'll store a clone and the original so we don't lose our place.
            HighlightTextNodes.push({
              active: node,
              ref: node.cloneNode()
            });
            // clear out the original.
            node.textContent = '';
          } else {
            // no text node.  go deeper.
            for(var i = 0, len = node.childNodes.length; i < len; i++) {
              recursiveGetTextNodes(node.childNodes[i]);
            }
          }
        })(NextHighlight.get(0))

        // Add the text back in, letter by letter.
        showText(HighlightTextNodes, 5);

        if (NextHighlight.hasClass('FullTime')) {
            CompleteReveal(MatchReportTop);
        }
}); 

// The letter-by-letter function.
function showText(target, interval) {
  // to know what we're currently working on, we need to filter
  // the text nodes by a check to see if they are already fully
  // "typed" out.  If the content doesn't match, keep it.  Also,
  // `shift()` off the first one.  That's the one we'll edit
  // this go around.
  var current = target.filter(function(a){
    return a.active.textContent != a.ref.textContent;
  }).shift();

  // if we have a node to work with, the process is not
  // completed. Once `current` is false, we know we've completed
  // the process.
  if (current) { 
    // grab the reference node's text up to the active node's
    // length +1 to get the current text plus one letter.
    current.active.textContent = current.ref.textContent.substr(0,current.active.textContent.length + 1);
    // rinse and repeat.
    setTimeout(function () {
      showText(target, interval);
    }, interval); 
  }
}

最佳答案

所以您想要增量显示文本,但它必须保留 HTML。您可以剥离标签并重新粘贴它们。您可以在解析文本时忽略标签,只需将它们完整粘贴即可。这是我首先想到的几个选项,但我都不喜欢它们。

如果你重新思考这个问题,可能会有更好的解决方案。您可以仅定位文本节点并增量显示这些文本节点中的每个字母。这是我经过深思熟虑后决定的计划。基本流程是这样的:

  1. 收集文本节点,存储其原始节点(仍附加到 DOM)
  2. 存储节点的克隆以供稍后引用
  3. 清空文本节点
  4. 递归调用定时方法,查找第一个与引用节点不匹配的节点
  5. 从引用节点向该节点添加一个字母
  6. 重复直到所有节点与引用节点匹配

// get the `newhidden`'s closest parent paragraph and prepare
// the array that will hold all the text nodes of that paragraph
var NextHighlight = $('.newhidden').first().closest('p'), HighlightTextNodes = [];

// recursively get the text nodes
(function recursiveGetTextNodes(node) {
  if(node.nodeType === 3) {
    // we're a text node? great, store it.  We'll store a clone
    // and the original so we don't lose our place.
    HighlightTextNodes.push({
      active: node,
      ref: node.cloneNode()
    });
    // clear out the original.
    node.textContent = '';
  } else {
    // no text node.  go deeper.
    for(var i = 0, len = node.childNodes.length; i < len; i++) {
      recursiveGetTextNodes(node.childNodes[i]);
    }
  }
})(NextHighlight.get(0))

// Add the text back in, letter by letter.
showText(HighlightTextNodes, 5);

// The letter-by-letter function.
function showText(target, interval) {
  // to know what we're currently working on, we need to filter
  // the text nodes by a check to see if they are already fully
  // "typed" out.  If the content doesn't match, keep it.  Also,
  // `shift()` off the first one.  That's the one we'll edit
  // this go around.
  var current = target.filter(function(a){
    return a.active.textContent != a.ref.textContent;
  }).shift();
  
  // if we have a node to work with, the process is not
  // completed. Once `current` is falsy, we know we've completed
  // the process.
  if (current) { 
    // grab the reference node's text up to the active node's
    // length +1 to get the current text plus one letter.
    current.active.textContent = current.ref.textContent.substr(0,current.active.textContent.length + 1);
    // rinse and repeat.
    setTimeout(function () {
      showText(target, interval);
    }, interval); 
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fuga, impedit <strong class="newhidden">labore <span>test</span> architecto</strong> quasi, possimus hic velit. Quibusdam quisquam illum quae doloremque, quis iste consequatur vero quaerat molestias doloribus dicta facilis.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas iusto laborum hic optio aliquam, adipisci a, dolore rem dolores harum voluptas cum! Similique, velit, commodi. Vero molestias, nobis ducimus nemo.</p>

关于javascript - 逐个字母地显示文本,但保留 html 格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44393056/

相关文章:

javascript - Angular 函数过滤器比较器示例

javascript - 由于夏令时时区,getDate() 给出错误的日期

javascript - 通过 Ajax 发送数组失败

java - 使用 java 下载 AJAX 生成的内容

jquery - CSS 3 - 模糊效果叠加模态背景

javascript - 如何验证股市数据

javascript - 计算后将JSON对象值转为十进制数

javascript - vue动态图片绑定(bind)

javascript - 通过 html 表单提交自定义标题

javascript - 我如何扩展一个 javascript 对象,以便在 native 没有 outerHTML 的浏览器中,我可以定义它?