在停用时停止setTimeout动画

时间:2014-09-09 14:30:56

标签: jquery hover css-transitions

所以我在悬停时继续播放这个动画:

div {
    background: #333333;
    padding: 40px 20px;
}

div span {
    background: #FFFFFF;
    padding: 10px;
    color: #333333;
    -webkit-transition: opacity 1s;
    -moz-transition: opacity 1s;
    -o-transition: opacity 1s;
    transition: opacity 1s;
}

div span.in {
    opacity: 1;
}

div span.out {
    -webkit-transition: opacity 0.3s;
    -moz-transition: opacity 0.3s;
    -o-transition: opacity 0.3s;
    transition: opacity 0.3s;
    opacity: 0;
}

jQuery的:

$(function() {

    $('div').hover(function() {

        var delay_time = 0;

        $(this).find('span').each(function() {

            delay_time += 400;
            var id = $(this).attr('id');

            setTimeout(function() {
                $('#' + id).removeClass('out').addClass('in');
            }, delay_time);

        });

    }, function() {
        $('div span').removeClass('in').addClass('out');
    });

});

http://jsfiddle.net/kssshhh/qs8bn1ua/

但是,只要你多次盘旋它,就会发生奇怪的事情。

我希望如此,当你徘徊时,所有的跨度都会同时消失。

我试图在悬停时添加.stop(),但这似乎没有做任何事情。

有人知道如何解决这个问题吗?

3 个答案:

答案 0 :(得分:0)

也许这是你的解决方案。

$(function() {
    function animate(id, run, delay_time){
        if(run){
            var tm = setTimeout(function() {
                    $('#' + id).removeClass('out').addClass('in');

                }, delay_time);
        }
        else clearTimeout(tm);
    }
   $('div').hover(function() {
    $(this).find('span').each(function() {
        var id = $(this).attr('id');
        animate(id, true, 400);
    });

 }, function() {
      $('div span').removeClass('in').addClass('out');
      animate('', false, 0);
  });

});

答案 1 :(得分:0)

在这里,你会去做你要求的事情。要更改动画,只需更改css动画即可。这将在浏览器重新绘制时立即对请求进行计时。然后它有一个时间延迟让浏览器处理它需要做的任何其他事情。此外,如果您在动画中间徘徊,它将更改回计数零并开始根据需要将它们更改为下一个设定值。

   <!DOCTYPE html>
    <html>
    <head>
    <title>example</title>
    <style>
        span[display=true]{
             /* Chrome, Safari, Opera */
            -webkit-animation-name: showMenu;
            -webkit-animation-duration: 2s;
            -webkit-animation-delay: 0s;
            -webkit-animation-iteration-count: 1;
            -webkit-animation-play-state: running;
            -webkit-animation-fill-mode: forwards;
            /* Standard syntax */
            animation-name: showMenu;
            animation-duration: 2s;
            animation-delay: 0s;
            animation-iteration-count: 1;
            animation-play-state: running;

        }

        span[display=false]{
             /* Chrome, Safari, Opera */
            -webkit-animation-name: hideMenu;
            -webkit-animation-duration: 2s;
            -webkit-animation-delay: 0s;
            -webkit-animation-iteration-count: 1;
            -webkit-animation-play-state: running;
            -webkit-animation-fill-mode: forwards;
            /* Standard syntax */
            animation-name: hideMenu;
            animation-duration: 2s;
            animation-delay: 0s;
            animation-iteration-count: 1;
            animation-play-state: running;
            animation-fill-mode: forwards;
        }

        @-webkit-keyframes showMenu {
            0% {}
            100% {
                opacity: 1;
            }
        }
        @keyframes showMenu {
            0% {}
            100% {
                opacity: 1;
            }
        }

        @-webkit-keyframes hideMenu {
            0% {}
            100% {
                opacity: 0.01;
            }
        }
        @keyframes hideMenu {
            0% {}
            100% {
                opacity: 0.01;
            }
        }


        div {
            background: #333333;
            padding: 40px 20px;
        }

        span {
            background: #FFFFFF;
            padding: 10px;
            color: #333333;
            opacity: 0;
        }

    </style>
    </head>
    <body>
        <div id="menu">
            <span display="false">lorem</span>
            <span display="false">ipsum</span>
            <span display="false">dolor</span>
            <span display="false">sit</span>
        </div>


    <script>
        var frames=0;
        var delay = 50;
        var count=0;
        var state="hide";
        var elements = document.getElementsByTagName("span");
        document.addEventListener('DOMContentLoaded',function(){
            document.getElementById("menu").addEventListener("mouseover",function(){
                count=0;
                state="show";
            });

            document.getElementById("menu").addEventListener("mouseout",function(){
                count=0;
                state="hide";

            });
            function loop(){
                setTimeout(function() {
                    if(count<elements.length){
                        if((frames%delay)==1){
                            switch(state){
                                case "show":
                                    elements[count].setAttribute("display","true");
                                break;
                                case "hide":
                                    elements[count].setAttribute("display","false");
                                break;
                            }
                            count++;
                        }
                    }
                    frames++;
                    window.requestAnimationFrame(loop);
                }, 5);
            }
            loop();
        });
    </script>
    </body>
    </html>

如果你想让鼠标一下子将其全部隐藏起来,只需将鼠标输出更改为此。

document.getElementById("menu").addEventListener("mouseout",function(){
    for(var x=0;x<elements.length;x++){
        elements[x].setAttribute("display","false");
    }
    state="hide";
});

答案 2 :(得分:0)

最终我最终这样做了:

$(function() {

    $('div').hover(function() {

            var time = 0;

            $(this).find('span').each(function() {

                time += 400;
                var id = $(this).attr('id');

                $('#' + id).delay(time).queue(function() {
                    $(this).removeClass('out').addClass('in');
                });

            });

        }, function() {
            $('div span').finish().removeClass('in').addClass('out');
        });

});

我不得不使用finish()而不是stop(true)或clearqueue(),它们似乎都没有正确清除队列。

帕特里克的回答非常简洁但是......