切换 Jquery 打字机效果

Toggling a Jquery typewriter effect

我正在学习 jQuery 作为实验,我尝试将 hide/show 切换效果与 Jason Frame (http://onehackoranother.com/projects/jquery/jquery-grab-bag/text-effects.html) 的打字机效果相结合。

一个页面上有 link 个,当点击其中一个时,会显示隐藏并触发字体效果。

这里是 jQuery 代码:

function toggleMe(a){
var e=document.getElementById(a);
if(!e)return true;
if(e.style.display=="none"){
e.style.display="inline-block"
}
else{
e.style.display="none"
}
return true;
}

(function($) {    

    $.fn.typewriter = function() {
        this.each(function() {
            var $ele = $(this), str = $ele.text(), progress = 0;
            $ele.text('');
            var timer = setInterval(function() {
                $ele.text(str.substring(0, progress++) + (progress & 1 ? '| ' : ''));
                if (progress >= str.length) clearInterval(timer);
            }, 100);
        });
        return this;
    }; 

})(jQuery);

d 而 HTML:

<p><a href="#" onclick="toggleMe('typewriter1'); $('#typewriter1').typewriter();">Lorem ipsum dolor sit amet</a><span id="typewriter1" style='display:none'>, consectetur adipiscing elit</span>.
<a href="#" onclick="toggleMe('typewriter2'); $('#typewriter2').typewriter();">Pellentesque ut facilisis nulla.</a>
<span id="typewriter2" style='display:none'>Mauris ultricies  <a href="#" onclick="toggleMe('typewriter3'); $('#typewriter3').typewriter();">suscipit</a> <span id="typewriter3" style='display:none'>dolor</span> in ultrices.</span></p>

显然有些地方出了问题,我真的不明白为什么。尤其: 1)不显示嵌套的link(typewriter3)。 HTML 似乎在隐藏的打字机范围内被剥离。
2) 跨度字符串的最后一个字符经常被遗漏。

有什么改进此代码的建议吗?

谢谢!

建议:不要混合使用 jQuery 和内联 onclick 处理程序。使用 jQuery 进行所有事件处理要简洁得多。您可以看到我是如何将所有处理程序组合成一个并使用 href 来确定目标的。

然后我开始从头开始编写新版本的打字机。它使用 contents() 迭代和 nodeType 检查来仅修改元素的实际文本部分。整个事情是递归的,所以它可以处理任意数量的嵌套元素。它还修复了代码中的一些最终状态错误(有时最后一个字符为 |)。

JSFiddle:http://jsfiddle.net/TrueBlueAussie/vLtL8uqa/1/

jQuery.fn.typewriter = function () {
    var recurse = function (node, delay) {
        // Only convert text nodes
        if (node.nodeType == 3) {
            var str = node.textContent || '';
            node.textContent = '';
            var progress = 0;
            // Initial timer to delay next descendant
            setTimeout(function () {
                // Repeat timer until complete
                var timer = setInterval(function () {
                    var ss = str.substring(0, progress++) + (progress & 1 ? '_' : '');
                    node.textContent = ss;
                    if (progress >= str.length) {
                        clearInterval(timer);
                        node.textContent = str;
                    }
                }, 100);
            }, delay * 100);
            delay += str.length;
        } else {
            var $node = $(node);
            if ($node.is(':visible')) {
                $(node).contents().each(function (index) {
                    delay = recurse(this, delay);
                });
            }
        }
        return delay;
    }
    this.each(function () {
        // Start with the specified node with delay = 0
        recurse(this, 0);
    });
    return this;
};

jQuery(function ($) {
    $('.typewriter').click(function (e) {
        var $target = $($(this).attr('href'));
        $target.toggle().typewriter();
        return false;
    });
});

开始时间逐渐延迟,使其看起来好像操作是按顺序发生的(实际上它们都是在同一帧上并行开始的)。

感谢 Jason Frame 的想法和我保留至今的几行代码 :)