HauntedSmores HauntedSmores - 6 months ago 18
Javascript Question

CSS transitions playing too many times; Added via jQuery

So I have 2 divs, one of them being hidden on load using jQuery .hide()

One div is id is menus and the other is prix-fix-menu

I want to fade and slide between the 2 with button clicks. Its a restaurant menu, so I want to smoothly scroll to the different sections of the menu (such as apps, entrees, dessert etc.) but then if the user clicks the Prix Fix button, the page will fade and slide out the regular menu and fade and slide in the Prix Fix menu. If they have the Prix Fix menu open, I want any of the links OTHER THAN the Prix Fix link, to take the user back to the main menu page, sliding out the Prix Fix and sliding in the regular menu.

To accomplish this, Im just dynamically adding and removing classes from Animate.css. The problem is that the animations keep playing more than once (even though Im using .one() method) . I believe it may be because Im listening to the animationend event to then play another animation causing a loop. But whats weird is that it plays it exactly 4 times, not infinitely.

Here's the javascript:

$('#prix-fix-menu, #catering-menu').hide();
$("a[href='#prix-fix']").on('click', function () {
$('#menus').removeClass().addClass('animated fadeOutLeft');
$('#menus').one('animationend webkitAnimationEnd', function () {
$("#menus").hide();
$('#prix-fix-menu').show().removeClass().addClass('animated fadeInRight');
});
});


$("a:not(a[href='#prix-fix'])").on('click', function () {
$('#prix-fix-menu').removeClass().addClass('animated fadeOutRight');
$('#prix-fix-menu').one('animationend webkitAnimationEnd', function () {
$("#prix-fix-menu").hide();
$('#menus').show().removeClass().addClass('animated fadeInLeft');
});
});


I also have a smooth scroll script (positioned after the previous script in at the bottom of the tag) working with the anchor links as well. Putting this here just in-case this is whats causing the problem even though I dont think so:

$('a[href^="#"]').on('click',function (e) {
e.preventDefault();

var target = this.hash;
var $target = $(target);

$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 900, 'swing', function () {
window.location.hash = target;
});
});


If more information like CSS or HTML are needed then let me know and Ill added but there's quite a lot of markup for the menu because of all the items.

Link to the live project: Project

Thanks in advance!

Answer

Following this CODE1

CODE1

$('#prix-fix-menu, #catering-menu').hide();
$("a[href='#prix-fix']").on('click', function () {
    //add this line
    $('#prix-fix-menu').unbind('animationend webkitAnimationEnd');

    $('#menus').removeClass().addClass('animated fadeOutLeft');
    $('#menus').one('animationend webkitAnimationEnd', function () {
        $("#menus").hide();
        $('#prix-fix-menu').show().removeClass().addClass('animated fadeInRight');
    });
});

$("a:not(a[href='#prix-fix'])").on('click', function () {
    //add this line
    $('#menus').unbind('animationend webkitAnimationEnd');

    $('#prix-fix-menu').removeClass().addClass('animated fadeOutRight');
    $('#prix-fix-menu').one('animationend webkitAnimationEnd', function () {
        $("#prix-fix-menu").hide();
        $('#menus').show().removeClass().addClass('animated fadeInLeft');
    });
});

your code may be caused multiple binding animationend webkitAnimationEnd, so animationend webkitAnimationEnd unbind before start animation.

WHY

Problem is animationend webkitAnimationEnd. animationend and webkitAnimationEnd is different event.

In your case, you tried to add two event at the same time. so another event leaves after trigger animation end. You can easily understand about this situation. Try following CODE2.

CODE2

$('#prix-fix-menu, #catering-menu').hide();
$("a[href='#prix-fix']").on('click', function () {
    $('#menus').removeClass().addClass('animated fadeOutLeft');
    $('#menus').one('webkitAnimationEnd', function () {
        $("#menus").hide();
        $('#prix-fix-menu').show().removeClass().addClass('animated fadeInRight');
    });
});

$("a:not(a[href='#prix-fix'])").on('click', function () {
    $('#prix-fix-menu').removeClass().addClass('animated fadeOutRight');
    $('#prix-fix-menu').one('webkitAnimationEnd', function () {
        $("#prix-fix-menu").hide();
        $('#menus').show().removeClass().addClass('animated fadeInLeft');
    });
});

In CODE2, remove only animationend event. It seems to work fine. But it has still problem when you click repeatedly same button. To work CODE2, you have to filter for user to click repeatedly same button using if-statement.

Comments