jQuery delegate events on dynamic elements with a click away handler Just thought I'd share this and see what kind of improvements could be made that I'm not aware of and taking advantage of.

The situation is this: I have a list of items on a page that have a button that opens a menu. I need a click away event as well as close others when a new menu is opened. Also some of the menu actions will replace items in the list which means I have new dynamic menu buttons on the page. 

To do this efficiently (as far as I can tell) you need to use event delegation and it ends up looking like this:

$(document).delegate( '.button', 'click', function(e){
    var $button = $(this);
    var $menu = $button.closest('.menu');
    e.stopPropagation();

    // Close others
    $('.button').each(function(){ 
      $(this).closest('.menu').removeClass('open'); 
    });

    // Toggle target open/close
    if( $menu.hasClass('open') ){
        $menu.removeClass('open');
    }
    else{
        $menu.addClass('open');
    }
    $(document).on('click', function(e){
        var $target = $(e.target);
        if( !$target.is( $( $menu.find('button') ) ) ){
            if( $menu.hasClass('open') ){
                $menu.removeClass('open');
            }
        }
    });
});


Maybe there's a better way?
I believe there is no better way. Regardless, we can shorten the code a little. Also note that .delegate() has been superceded by .on() since jQuery 1.7, so I replaced your delegate with on.

$(document).on( 'click', '.button', function(e){
    var $button = $(this);
    var $menu = $button.closest('.menu');
    e.stopPropagation();

    // Close others-assumed you want all menus closed
    $('.menu').not($menu).removeClass('open'); 

    // Toggle target open/close
    $menu.toggleClass('open');

    $(document).on('click', function(e){
        //This function will only run when e.target isn't a button
        //Your $target.is($menu.find('button')) will always be false

        if( $menu.hasClass('open') ){
            $menu.removeClass('open');
        }
    });
});


If this does not do the same thing, you really need to share your html structure so we can get a better idea of your mark-up.

Edit
To work around the fact that the document click event is assigned every time you click on a button, you could do something like the following:

$(document).ready(function() {
   var $menu;
   $(document).on( 'click', '.button', function(e){
      var $button = $(this);
      $menu = $button.closest('.menu');
      e.stopPropagation();
      $('.menu').not($menu).removeClass('open'); 
      $menu.toggleClass('open');
   });
   $(document).on('click', function(e){
      if($menu &amp;&amp; $menu.hasClass('open') ){
            $menu.removeClass('open');
        }
   });
)}