CSS Animation pausing when element is hidden

2020-04-11 10:56发布

问题:

I'm working on adding click/touch animations to buttons on a project I'm working on, and I've come across a frustrating problem concerning animating buttons which show and hide elements.

The project is a single page mobile web app with a handful of buttons on it. I'm using jQuery to set a css keyframe animation on a button when it's pressed. The button hides the current page, and shows a new one. The problem is, when I click the button, the page changes before the animation is complete, and the animation is paused whilst the container is hidden. When the container is re-shown, the animation continues from where it was hidden, then the webkitAnimationEnd event triggers.

The containers are shown and hidden with:

display: none;

I can't change this to:

visibility: hidden;

because the container will still take up space. Are there any simple ways I can force the animation to be removed when the element becomes invisible, or force the animation to continue when the container is hidden?

Edit: For clarification, this is the keyframe animation I'm applying in the javscript:

@-webkit-keyframes shrink
{
    0%
    {
        -webkit-transform: matrix(1, 0, 0, 1, 0, 0);
    }
    50%
    {
        -webkit-transform: matrix(0.95, 0, 0, 0.95, 0, 0);
    }
    100%
    {
        -webkit-transform: matrix(1, 0, 0, 1, 0, 0);
    }
}

And this is the javascript I've got to apply the animation to the element:

$('body').on(_context.settings.platformInfo.device.touch ? 'touchstart' : 'mousedown', '.shrink', function ()
{
    var $item = $(this);

    $item.one('webkitAnimationEnd', function ()
    {
        $item.css({ '-webkit-animation': 'none' });
    }).css({ '-webkit-animation': 'shrink 250ms forwards' });
});

回答1:

You could put the CSS definition of the animation in a separate class and add or remove this extra class based on visibiity:

#SomeDiv{ .... }
.MyAnimation{ .... }

$('#SomeDiv').addClass('MyAnimation').show();
$('#SomeDiv').hide().removeClass('MyAnimation');


回答2:

You could try setting visibility: hidden; but also absolutely position the element off-screen, e.g position: absolute; left: -500px; /* Or whatever it takes */. In fact, you might not even need to set the visibility. It feels a bit hacky though.



回答3:

I guess your problem could be solved if the animation for hiding the current page just waits until the button's animation is complete. So you'd have to trigger the page animation in the "on complete" callback of the button's animation:

$("#button").click(function(){
    $(this).animate({
        //animation parameters
    }, 1000, function() {
        //button animation complete, change pages
    });
});

Test it here: http://jsfiddle.net/Y5HSU/



回答4:

I've found a solution which will work for this particular problem, although I'm not massively fond of it. Adding a setTimeout into the mix means that even when the container is hidden, the animation will be removed after 250ms (in this case).

$('body').on(_context.settings.platformInfo.device.touch ? 'touchstart' : 'mousedown', '.shrink', function ()
{
    var $item = $(this);

    setTimeout(function ()
    {
        $item.css({ '-webkit-animation': 'none' });
    }, 250);

    $item.css({ '-webkit-animation': 'shrink 250ms forwards' });
});

The main problem with this is if the browser is particularly slow at executing the animation, and the timeout fires too soon cutting the animation off.



回答5:

In CSS :

.hidden .myAnimation {
   /* Will reset and prevent your animation
      from running when the element is hidden. */
   animation: none;
}