我正在学习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)跨度字符串的最后一个字符经常被遗漏。
有任何改进此代码的建议吗?
谢谢!
答案 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这个想法和我保留的几行代码:)