StuBlackett
StuBlackett

Reputation: 3857

jQuery slideToggle - Loading Twice (Open - Then Close)

I've built a site with a Mobile Navigation,

I'm using jQuery to do a slideToggle, But I have a few checks in place, To see if the user has opened the search bar / notifications bar, Then showing hiding so that you only see one of the items at a given time.

My jQuery code is as follows (I'll also provide a Fiddle)

$(document).ready(function()
{
    // Mobile Nav Toggle...
    $('.nav-toggle').click(function()
    {
        // // Check If Other Items Are Open....
        if($('.mobile-search-form:visible'))
        {
            $('.mobile-search-form').hide();
        }
        // // Check If Other Items Are Open....
        if($('.mobile-notifications:visible'))
        {
            $('.mobile-notifications').hide();
        }

        $('nav').slideToggle();

        accordion_links();

        return false;
    })

    // Add a Chevron Class To Links (For Mobile Nav)...
    $(function() {
        $('nav ul li a').each(function()
        {
            if ( $(this).parent('li').children('ul').size() > 0 )
            {
                $(this).addClass('chevron-down');
            }
        });
    });

    function accordion_links()
    {
        $('.chevron-down').click(function()
        {
            $(this).next('ul.sub-nav').slideToggle();

            if($(this).parent('li').hasClass('open'))
            {
                $(this).removeClass('chevron-up');
                $(this).addClass('chevron-down');
                $(this).parent('li').removeClass('open');
            }
            else
            {
                $(this).removeClass('chevron-down');
                $(this).addClass('chevron-up');
                $(this).parent('li').addClass('open');
            }
        })
    }

    // Toggle Search Form (On Mobile)....
    $('.search-link').click(function()
    {

        // Check If Notifications / Search Form Are Visible...
         if($('nav:visible'))
         {
                $('nav').slideUp();
         }

         if($('.mobile-notifications:visible'))
         {
            $('.mobile-notifications').hide();
         }

        $('.mobile-search-form').slideToggle();

        return false;
    })

    // Toggle Notifications On Mobile...
    $('a.notifications').click(function()
    {
        // Check If Notifications / Search Form Are Visible...
         if($('nav:visible'))
         {
            $('nav').hide();
         }

         if($('.mobile-search-form:visible'))
         {
            $('.mobile-search-form').hide();
         }

        $('.mobile-notifications').slideToggle();

        return false;
    })

    // Close Notification Block
    $('.close-notification').click(function()
    {
        $('.notification').fadeOut();
    })


})

The problem I have, Is the toggle works first time around, But when you click say the search-link, Then load the nav in. The slideToggle tries to do the animation twice (Open then Close)

A jsFiddle is here

Why would it be doing this? I can only assume my logic is wrong on this.

Upvotes: 7

Views: 5426

Answers (5)

Maahi Bhat
Maahi Bhat

Reputation: 191

e.stopImmediatePropagation();

This will solve your problem.

Upvotes: 3

Doaa Magdy
Doaa Magdy

Reputation: 526

Sometimes, jQuery actions run twice if they get called many times. That happens because there are some pending actions in the execution queue which disturb the actions flow.

So I suggest using clearQueue() method in the beginning of your click method, that will guarantee clearing any uncompleted actions before starting the execution of your logic.

Here's the documentation of clearQueue() method https://api.jquery.com/clearQueue/

Upvotes: 2

Aimeé RP
Aimeé RP

Reputation: 114

Try your slideToggle in else condition, because you only have if conditions without else and it always tries to do the animation.

And optionally, comment return false;, I had problems with this line, because sometimes toggle doesn't Works.

Upvotes: 2

user6079755
user6079755

Reputation:

Update Delegated function change it:

$('.chevron-down').click(function()

for this:

$(document).on("click",'.chevron-down', function()

Work better on ajax.

Upvotes: 1

jeremykenedy
jeremykenedy

Reputation: 4275

I modified line 39 of the JS with the .stop() and it works (I believe this is the behavior you want):

$(this).next('ul.sub-nav').stop().slideToggle();

https://jsfiddle.net/hc8cad7c/1/

Ok, Here is the second attempt with removing the slideToggle() and using slideUp() and slideDown() functions in place of and it appears working at first glance but I do not think it is fully worked out after a couple clicks...

Here are the lines I changed:

function accordion_links()
{
    $('.chevron-down').click(function()
    {
        if($(this).parent('li').hasClass('open'))
        {
            $(this).removeClass('chevron-up');
            $(this).addClass('chevron-down');
            $(this).parent('li').removeClass('open');
    $(this).next('ul.sub-nav').slideUp();
        }
        else
        {
            $(this).removeClass('chevron-down');
            $(this).addClass('chevron-up');
            $(this).parent('li').addClass('open');
    $(this).next('ul.sub-nav').slideDown();
        }
    })
}

And the fiddle: https://jsfiddle.net/hc8cad7c/2/

Upvotes: 3

Related Questions