Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery click(function()) does not use variable on first click

I have this tiny script:

var $totalHeight;

$(document).ready(function() {
    $totalHeight = $('#sidebar-container').innerHeight();
    $('.sidebar-heading').each(function() {
        $totalHeight = ($totalHeight - $(this).outerHeight());
    });

    $('.sidebar-contents').each(function() { 
        if ($(this).hasClass('active')) {
            $(this).css('height',$totalHeight);
        }
    });

    $('.sidebar-heading').click(function() {
        $('.sidebar-contents').slideUp().removeClass('active').addClass('inactive')/*.css('height','').removeAttr('style')*/;
        $('.sidebar-heading').removeClass('active')/*.next().slideUp()*/;
        $(this).addClass('active').next().addClass('active').removeClass('inactive').css('height',$totalHeight).slideDown();
    });
});

I am pretty sure it's obvious what it is supposed to do.

My problem is: The first click on a ('.sidebar-heading') does not apply the desired $totalHeight to its sibling. The following clicks, it does. What am I doing wrong?

I have a draft-HTML with this code in action. I commented out those parts above to check, where the bug is, but couldn't figure it out anyway.

like image 961
rob_st Avatar asked Dec 14 '25 06:12

rob_st


2 Answers

The slideUp() animation takes a while to run and cleans up all the heights and display styles after it gets done. This erases the setting you made in the next two lines.

Try waiting until slideUp() is done to do the other ones.

   $('.sidebar-heading').click(function() {
        var self = this;
        $('.sidebar-contents').slideUp(undefined, function() {
            $('.sidebar-heading').removeClass('active')/*.next().slideUp()*/;
            $(self).addClass('active')
                .next().addClass('active').removeClass('inactive')
                .css('height',$totalHeight).slideDown();
        }).removeClass('active').addClass('inactive')
        /*.css('height','').removeAttr('style')*/;
    });

I figured this out by running in Chrome with the debugger and noticing that the styles were changing in a wierd way. The first click on the 2nd heading would leave the height set on the 1st heading even though the code was clearing it. That means something was, maybe, setting it wrong. So I tried the above code on the jsFiddle someone set up. Lo and behold ...

like image 200
Lee Meador Avatar answered Dec 16 '25 23:12

Lee Meador


You can also let the fx function set the height by itself to avoid conflict mentioned in @LeeMeador's answer.

Since the slideDown() doesn't accept any css value, we can use the animate() function directly instead.

$('.sidebar-heading').click(function () {
    $('.sidebar-heading').removeClass('active');
    $('.sidebar-contents').removeClass('active').addClass('inactive').stop().animate({ height: '0px' });
    $(this).addClass('active').next().addClass('active').removeClass('inactive').stop().animate({ height: $totalHeight + 'px' });
});

In addition, use stop() before perform any animation to prevent weird behavior if you click the heading again while the previous animation haven't finished.

Modified jsfiddle: http://jsfiddle.net/z62tr/4/

like image 21
runTarm Avatar answered Dec 16 '25 22:12

runTarm



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!