Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind to custom CSS animation end event with jQuery or JavaScript?

We have multiple animations against the same object. We need to take different actions when each of these animations end.

Right now, we bind to the webkitAnimationEnd event, and use a gnarly if/then statement to handle each animation differently.

Is there a way to essentially create custom webkitAnimationEnd events, allowing us to fire a specific event handler when a specific animation ends? For instance, fire handler1 when animation1 ends and fire handler2 when animation2 ends.

We're building for Webkit browsers, specifically Mobile Safari.

Thanks!

like image 228
Crashalot Avatar asked Sep 19 '12 16:09

Crashalot


1 Answers

For a simple event-trigger, you can pass a function to jQuery's trigger() method and use the returned value of that function to call a trigger a specific event (which can then be listened-for:

function animEndTrigger(e) {
    if (!e) {
        return false;
    }
    else {
        var animName = e.originalEvent.animationName;
        return animName + 'FunctionTrigger';
    }
}

$('body').on('bgAnimFunctionTrigger fontSizeFunctionTrigger', function(e){
    console.log(e);
});

$('div').on('webkitAnimationEnd', function(e) {
    $(this).trigger(animEndTrigger(e));
});

JS Fiddle demo.

You can, of course, also use the called function to either trigger the event itself or assess the passed parameters to determine whether or not to return an event at all:

One method to assess for a particular event to trigger is to use an object:

var animations = {
    'bgAnim': 'aParticularEvent'
};

function animEndTrigger(e) {
    if (!e) {
        return false;
    }
    else {
        var animName = e.originalEvent.animationName;
        return animations[animName] ? animations[animName] : false;
    }
}

$('body').on('aParticularEvent', function(e) {
    console.log(e);
});

$('div').on('webkitAnimationEnd', function(e) {
    $(this).trigger(animEndTrigger(e));
});​

JS Fiddle demo.

Though, in this case, the return false should be altered so as not to provide the error Uncaught TypeError: Object false has no method 'indexOf' (which I've not bothered, as yet, to account for).

The following causes the called-function (animEndTrigger()) to directly trigger() the custom event (which requires an element on which to bind the trigger() method) and also avoids the Uncaught TypeError above:

var animations = {
    'bgAnim': 'aParticularEvent'
};

function animEndTrigger(e, el) {
    if (!e || !el) {
        return false;
    }
    else {
        var animName = e.originalEvent.animationName;
        if (animations[animName]) {
            $(el).trigger(animations[animName]);
        }
    }
}

$('body').on('aParticularEvent', function(e) {
    console.log(e);
});

$('div').on('webkitAnimationEnd', function(e) {
    animEndTrigger(e, this);
});​

JS Fiddle demo.

Of course you're still, effectively, using an if to perform an assessment, so I can't be particularly sure that this is any tidier than your own already-implemented solution.

like image 106
David Thomas Avatar answered Oct 18 '22 09:10

David Thomas