javascriptjqueryeventsjquery-eventsjquery-click-event

Binding two click events on one button with different attributes not working


Anyway, I got this button that is supposed to open my nav.

HAML:

%button#nav-toggle{ :navigate => 'false' } Menu

HTML:

<button id='nav-toggle' navigate='false'>Menu</button>

And I'm binding two clicks on it like this:

jQuery

$(document).ready(function(){
  
  $("#nav-toggle[navigate='false']").click(function(){
    console.log("opening nav");
    $("#nav-toggle").attr('navigate','true'); 
    
    $( "#masthead" ).animate({
        height:'100vh',
    }, {
      duration: 1000,
      queue: false,
      done: function() {
        console.log("first done");  
      }
    }
    );
  });

  $("#nav-toggle[navigate='true']").click(function(){
    console.log("closing nav");
    $("#nav-toggle").attr('navigate','false'); 
    $( "#masthead" ).animate({
        height:'10vh',
    }, {
      duration: 1000, 
      queue: false,
      done: function() {
        console.log("second done"); 
      }
    }
    );
  });
});

For some reason, when I click the button for the second time (When its navigate-attribute is set to true, it still launches the first event of those two.

What am I missing here?

Full code here: Codepen


Solution

  • You need to delegate the event.

    Take a look at this http://codepen.io/anon/pen/jAjkpA?editors=1010

    You need to bind the event to a parent in this case the .hamb-container.

    Here's a link to understand how delegation and event bubbling works https://learn.jquery.com/events/event-delegation/.

    Basically as a summary:

    When an event is triggered it bubbles the event all the way up to your root HTML tag.

    That is good for when you want to add dynamic content or in your case pick out an attribute that changes dynamically.

    So how do we bind to dynamic content? Simple. We surround them with a static container and bind to that instead. Additionally, we let JQuery know what the dynamic content will be. So Jquery will listen for an event on the static element and check if it actually originated from the element you were looking for.

    Something like this

    $( "#staticAncestor" ).on( "click", "#DynamicContent", function( event ) {
    
    });
    

    Hope this helps. Happy coding!