I have some JQuery code where an if-then statement is being run after a .slideToggle event. I just don't understand why the if section is still being run when it would appear the if statement is false. Code incoming:
JQuery:

$(function() {
    var pull        = $('#pull');
        menu        = $('div#nav ul');
        menuHeight  = menu.height();
        head        = $('div#welcome');
        down        = true;

    $(pull).on('click', function(e) {
        e.preventDefault();
        menu.slideToggle(function(){
            if(down = true){
                $(head).animate({paddingTop:'287px'}, {duration: 0, queue: false});
                down = false;
            }
            else{ 
                $(head).animate({paddingTop:'125px'}, {duration: 0, queue: false});
                down = true;
            }
        });

After the .slideToggle event runs once it seems to work fine, but run it again and it just runs the first line again. I even used .consoleLog() to make sure that "down = false". So it seems to just keep running the if statement and I don't understand why

Member Avatar for stbuchok

you are assigning down to be true in your if statement

if(down){
    //do stuff if down is true
}
else{
    //do stuff if down false
}

or

if(down == true){
    //do stuff if down is true
}
else{
    //do stuff if down false
}

Alright so I changed it to this:

if(down == true){
    $(head).animate({paddingTop:'287px'}, {duration: 0, queue: false});
    down = false;
}
else{ 
    $(head).animate({paddingTop:'125px'}, {duration: 0, queue: false});
    down = true;
}

But now it ONLY runs the else statement, it won't run the if statement. There is no winning XD

Member Avatar for stbuchok

That just means that down is always false, you have to find out why. Try stepping through the code with a dev tool for your browser.

Also, I'd change it to the following:

var topPadding = '125px';

if(down)
    topPadding = '287px';

$(head).animate({paddingTop: topPadding}, {duration: 0, queue: false});

down = !down;

Also, your head selector doesn't need div in the from as you are selecting based on id (same goes for menu).

Ok so I tried to track down the problem a little bit by trying to add some console.log()'s and this is what I used as the code (by the way as soon as I figure this problem out I'm going to take your advice and use the code you suggested, I just want to make sure I don't confuse myself... or anyone else).

menu.slideToggle(function(){
    if(down){
        $(head).animate({paddingTop:'287px'}, {duration: 0, queue: false});
        down = !down;
        console.log('Yup');
    }
    else{ 
        $(head).animate({paddingTop:'125px'}, {duration: 0, queue: false});
        down = true;
        console.log('Nope');
    }
});

So when I ran this and toggled the menu it actually printed both "Yup" and "Nope" at the same time, as if they were both being ran. Yup coming first, Nope coming second. So what I'm thinking is that maybe it's running this code at the initial click AND at the end of the .slideToggle. So now we know the reason it's keeping down as "true". Because the else section keeps running last.

Member Avatar for stbuchok

Do you have any other click events on the page? Put an alert or console.log statement just before menu.slideToggle. I bet your click event is firing twice.

Aha! I've figured out what's going. So it's not that there are two click events, because I made sure right above menu.slideToggle using an alert. But, I put a console.log('yes') on the inside of the menu.slideToggle like this:

menu.slideToggle(function(){
            console.log('yes')
            if(down){
                $(head).animate({paddingTop:'287px'}, {duration: 0, queue: true});
                down = !down;
            }
            else{ 
                $(head).animate({paddingTop:'125px'}, {duration: 0, queue: false});
                down = true;
            }
        });

and it is printing "yes" twice. As soon as the slideToggle ends it seems to print it twice instantly. So that's why it appears to run the else statement "last". It's because when it runs it twice instantly it makes down not true first, then it runs again (instantly) thinking down is not true so it then it runs the else statement making it true. So no matter what, if it keeps running them twice it's going to always be true. Because that else statement will be run last every time.

Well I never exactly figured out why it would fire twice, But, I changed up the code and used this, and now it works. I guess that's what I get for trying to cut corneres haha.

$(function() {
    var pull        = $('#pull');
        menu        = $('div#nav ul');
        menuHeight  = menu.height();
        head        = $('div#welcome');
        down        = true;
    $(pull).on('click', function(e) {
        e.preventDefault();
        menu.slideToggle();
    });
    $(pull).click(function(){
        if(down){
            $(head).delay(400).animate({paddingTop:'287px'}, {duration: 0, queue: true});
            down = !down;
        }
        else{ 
            $(head).animate({paddingTop:'125px'}, {duration: 0, queue: false});
            down = true;
        };
    });
});

Thanks for the help everyone! Greatly appreciated!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.