通过char淡化char(保持DOM完整)

时间:2013-02-03 13:46:08

标签: javascript jquery

我想为文本设置动画,使其逐字逐渐消失。我实际上设法做到这一点,而没有保持DOM完整,它看起来像这样:

// make each character an own span element
// abc will become <span>a</span><span>b</span><span>c</span>
var elements = $(elemId).text().split('');
$(elemId).text('');

for (var i = 0; i < elements.length; i++) {
    $(elemId).append('<span>' + elements[i] + '</span>');
}

// fade in all spans one by one
$(elemId + " span").each(function(index) {
    $(this).delay(speed * index).fadeIn(300);
});

但这会打破我文本中可能存在的元素,特别是强大的元素,还有列表或表格。所以我想到了这两种可能的解决方案:

  • 使用jQuery遍历DOM并使用<span>包装每个字符,但不删除其他元素。然后我们仍然有问题,表行将始终显示(只是空)
  • 使用jQuery遍历DOM并使用<span>包装每个字符,并将相互禁用的元素禁用到display: none。然后回溯它并显示它出现的东西(span和其他元素)。这可能会暂时中断HTML(<ul>内部没有<li>等等,但我想所有浏览器都能够很好地处理它。)

我从contents()方法开始,但我没有真正开始。

这是我目前所拥有的,但它根本不会取代任何东西(即使它至少找到了一些文字):

$(elemId).contents().each(function() {
    if (this.nodeType == 3) {
        var elements = $(this).text().split('');
        alert(elements);
        // does not delete anything, but it would also break 
        // if it deleted something
        // because text('') goes over elements like <strong> etc.
        $(this).text('');
        alert($(this).text());

        for (var i = 0; i < elements.length; i++) {
            $(this).append('<span>' + elements[i] + '</span>');
        }
    }
});

那么我需要做些什么才能正确获取文本和标签?如果所有内容都像上面那样设置,我想这只是递归地使用contents()并再次设置所有元素的可见性。但正确添加我的<span>似乎很难。

一些例子

I am <strong>AB</strong>

应该成为:

<span display="none">I</span><span display="none"> </span>
<span ...>a</span><span ...>m</span><span ...> </span>
<strong ...><span ...>A</span><span ...>B</span></strong>

1 个答案:

答案 0 :(得分:2)

.contents()不会遍历DOM。您需要应用.find("*")来获取所有后代,然后对其应用.contents()

$("selector").find("*").andSelf().contents().each(function(){
  if(this.nodeType == Node.TEXT_NODE){
    $(this).replaceWith($.map(this.data, function(c){
      return "<span>" + c + "</span>";
    }).join(""));
  }
});

这是元素后代中每个角色完成的工作。我想你知道你需要非常谨慎地使用。