我试图让元素在用户点击时随着动画的淡出而出现和消失。我有这个工作,但如果用户连续快速点击两次,或者在动画完成之前,就会出现问题。我知道这个问题将与运行循环、事件和动画的时间等有关,但作为一名html/js的新手,我对这些问题的经验不足,无法知道最佳解决方案。
这是一把小提琴,如果你点击第一行,每次点击之间等待几秒钟,它就会起作用,如果你疯狂点击,你很快就会发现问题。
感谢
http://jsfiddle.net/mungbeans/wqUgC/
这是一个比您想象的更常见的问题。问题是您已经设置了一个事件来将元素设置为display: none
。但如果您再次单击,则表示您希望停止该事件的发生。因此,您需要做的是保留对事件的引用(setTimeout()
返回此值),以便在需要取消元素的隐藏时可以对该引用调用clearInterval()
:
var listener = (function() {
var interval = 0; //A variable to retain the interval
return function() { //return the original function into listener
var title = document.getElementById('title');
//dismiss any plans to hide/show the element because we've changed our minds
// (if the event already fired, this does nothing, which is fine):
clearInterval(interval);
if (title.dataset.displayed == 'yes') {
title.dataset.displayed = 'no';
setTimeout(function () {
title.style.webkitTransition = "opacity 2.0s ease";
title.style.opacity = 0.0;
}, 0);
//don't forget to hold onto the interval!
interval = setTimeout(function() { title.style.display = 'none'; }, 2000);
}
else {
title.dataset.displayed = 'yes';
title.style.display = 'block';
//It's probably not necessary to retain the interval here.
// But it doesn't hurt anything.
interval = setTimeout(function () {
title.style.webkitTransition = "opacity 2.0s ease";
title.style.opacity = 1.0;
}, 0);
}
};
}());
var li = document.getElementById('list');
li.addEventListener("click", listener, false);
请注意,我将侦听器函数封装在一个更大的、立即调用的函数表达式中,该表达式返回原始函数。我这样做是为了从listener()
的一个调用到下一个调用保留interval
。您也可以使interval
成为一个全局变量,但这些都很麻烦,而且这个解决方案更令人愉快地自给自足。
当我把它换成你的JSFiddle时,似乎工作得很好。代码的其余部分做得很好!
一个快速的解决方案就是添加一个简单的锁,防止任何其他动画被激发。我在这里做到了。
代码上的一些注释-代码上的动画锁定可能不应该被代码的其他部分访问,所以我把它放在一个单独的上下文中。此外,为了确保一切都在正确的时间启动,我添加了一个整数控件"animate time"来处理动画速率。