动画、计时和运行循环等问题

Issue with animation and timing and run loops etc

本文关键字:运行 循环 等问题 动画      更新时间:2023-09-26

我试图让元素在用户点击时随着动画的淡出而出现和消失。我有这个工作,但如果用户连续快速点击两次,或者在动画完成之前,就会出现问题。我知道这个问题将与运行循环、事件和动画的时间等有关,但作为一名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"来处理动画速率。