Joe Lowery Joe Lowery - 1 year ago 53
Javascript Question

jQuery toggle hides selector

I want to use the jQuery toggle() function to slide an off-screen div (#mobileNav) in from the left when an element (#mobileMenu) is clicked and then when the element is clicked again, the div slides off-screen again. I've got the sliding working on click, but the trigger element is then hidden - a display:none is injected into the tag - which makes it impossible to click again slide the div back out. Here's the relevant code:

$('#mobileMenu').click(function() {
$("#mobileMenu").toggle(function() {
$('#mobileNav', this).animate({left: '0' });
}, function() {
$("#mobileNav", this).animate({left: '-380px'});

is initially set to
left: -380px

<div class="mobile-menu-icon">
<p><a id="mobileMenu" href="#">&#9776;</a></p>

The answer may use scoping, but I can't seem to grasp how that works.

As always - thanks for any and all help - Joe

Answer Source

The issue is because the toggle() method no longer works in the manner you are expecting. The 'toggle between functions' signature was deprecated in 1.8 and removed in 1.9.

Instead you need to handle the change in behaviour yourself. In this case, by checking the current left position of the element:

$('#mobileMenu').click(function() {
    $(this).toggle(function() {
        var leftPos = parseInt($(this).css('left'), 10) == 0 ? '-380px' : 0;
        $('#mobileNav').animate({ left: leftPos });

Alternatively, and preferably, you could perform the animation in CSS and just use toggleClass to trigger it:

#mobileNav {
    left: 0;
    transition: left 0.5s;
} {
    left: -380px;
$('#mobileMenu').click(function() {

Finally, note that your use of a contextual id selector ($("#mobileNav", this)) is redundant as id attributes should be unique within a document, therefore the context selector is moot.