Masu
Masu

Reputation: 1668

Why does this callback not unbind itself to transitionEnd after completing one animation?

hi im trying to bind a function to webkitTransitionEnd using jquery's .one method. when i do:

$element.one( "transitionend MSTransitionEnd webkitTransitionEnd oTransitionEnd",
function(e) { 
    $element.removeClass( ".alert-resets" ) 
 });

it doesn't unbind to the transitionend event. instead it removes the class every time it does the transition

heres the jsfiddle: http://jsfiddle.net/DVC5A/

ok i found this solution on SO:

How do I normalize CSS3 Transition functions across browsers?

Upvotes: 2

Views: 2185

Answers (3)

1nfiniti
1nfiniti

Reputation: 2070

Don't use one()... use on() (like normal) and then unbind your event handler with off() at the end of your transition end event handler

$("#button-element").on('click', function(e){
    var transEnd = 
        "transitionend MSTransitionEnd webkitTransitionEnd oTransitionEnd";

    // ... trigger your css3 transition
    $('#el').addClass('whatever');

    // then ...
    $('#el').on(transEnd, function (e) {
        // do stuff
        $('#el').removeClass('whatever');

        //unbind event handler
        $('#el').off(transEnd);

    });

}

Upvotes: 4

antishok
antishok

Reputation: 2910

The docs for .one() explicitly state: "If the first argument contains more than one space-separated event types, the event handler is called once for each event type.".

I don't know if there is a more proper way to deal with this type of event (listening for only one event name would probably work but I donno how that'd work cross-browser). But in any case you can just unbind it yourself with .off(), and you can use an event namespace to make that easier:

$(".my_butt").on("click", function (e) {
    $(".block").addClass("in");

    $(".block").on("transitionend.my MSTransitionEnd.my webkitTransitionEnd.my oTransitionEnd.my", function (e) {
        var el = $(this);
        el.off('.my');
        setTimeout(function () {
            el.removeClass("in");
        }, 3000);
    });
});

JSFiddle: http://jsfiddle.net/DVC5A/6/

Upvotes: 3

adeneo
adeneo

Reputation: 318232

I really don't get what you're trying to do, but I'll try anyway? This is your code:

$(".my_butt").on("click", function (e) {
    $(".block").addClass("in");

    $(".block").one("transitionend MSTransitionEnd webkitTransitionEnd oTransitionEnd", function (e) {
        console.log('pl')
        setTimeout(function () {
            $(".block").removeClass("in");
        }, 3000);
    });
});

So everytime you click the button you rebind the transitionEnd event for one() more time as the event handler is inside the click event handler for the button, so of course it removes the class everytime you click the button?

To attach the transitionEnd event handler just one time for each time the document loads, just move the event handler out of the click function for the button ?

$(".my_butt").on("click", function (e) {
    $(".block").addClass("in");
});

$(".block").one("transitionend MSTransitionEnd webkitTransitionEnd oTransitionEnd", function (e) {
    setTimeout(function () {
        $(".block").removeClass("in");
    }, 3000);
});

Upvotes: 1

Related Questions