2015-02-06 74 views
1

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

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

这里是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)不显示嵌套链接(打字机3)。看起来,HTML在一个隐藏的打字机范围内被剥离。
2)跨度字符串的最后一个字符经常被忽略。

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

谢谢!

+0

这个插件是不是设计有*嵌套工作*跨度,因为它的工作原理是替换文字内容。任何子DOM元素都被忽略。你需要完全重写它,以允许递归再生所有可见的后代。 – 2015-02-06 15:31:08

+0

完整重写,完整递归,如下。我有一些想法可以让这个概念更进一步,所以非常感谢。享受:) – 2015-02-06 17:15:08

回答

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的想法,我保留至今的几行代码的 :)

+0

非常感谢您的努力。看看你用原始插件做了什么很有意思。我很感兴趣,看看我的问题激发了你的项目!再次感谢... – WITI 2015-02-08 20:04:59

+0

注意:* this *版存在严重的*浏览器兼容性问题。 – 2015-02-09 08:35:03