切换Jquery打字机效果

时间:2015-02-06 14:50:58

标签: jquery toggle

我正在学习jQuery,作为一个实验,我试图将隐藏/显示切换效果与Jason Frame(http://onehackoranother.com/projects/jquery/jquery-grab-bag/text-effects.html)的打字机效果结合起来。

页面上有链接,单击一个链接时会显示隐藏,并触发类型效果。

这是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)不显示嵌套链接(typewriter3)。似乎HTML在隐藏的打字机范围内被剥离 2)跨度字符串的最后一个字符经常被遗漏。

有任何改进此代码的建议吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

建议:不要混用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这个想法和我保留的几行代码:)