Search code examples
jquerybindingthisbinddelegation

jQuery events, getting correct context of $(this)


I need to declare $featuredImage outside of mouseenter and mouseleave events with the correct context of $(this) to avoid code duplication. As you all know $(this) outside of mouseenter/mouseleave is an empty object. I want to bind $(this) to the correct context to assign $featuredImage just once and access it from both functions, but I don't seem to find the good way to do it.

function postThumbOverlay() {

  var $featuredImage;

  $(document).on({
      mouseenter: function(e) {
          // duplicated
          $featuredImage = $(this).parents('.grid').children( '.entry__featured-image' );
          $featuredImage.find('.entry__featured-image--overlay').addClass( 'show--overlay' );
          e.stopPropagation();
      },
      mouseleave: function() {
          // duplicated
          $featuredImage = $(this).parents('.grid').children('.entry__featured-image');
          $featuredImage.find('.entry__featured-image--overlay').removeClass( 'show--overlay' );
      }
  }, '.entry-link');
}

The reason I'm not using .on('hover') is because doing so stops working after an AJAX call and I need to use mouseenter and mouseleave separately.


Solution

  • Extract it to a method -

    function getFeaturedImageElement($this){
     return $this.parents('.grid').children( '.entry__featured-image' );
    }
    

    and call it in the events - var $featuredImage = getFeaturedImageElement($(this));

    And if you really want to avoid querying the DOM on each events, then have a check inside that method (keeping $featuredImage as global as you did) -

    var $featuredImage;
    function getFeaturedImageElement($this){
       if(!$featuredImage){ 
         $featuredImage = $this.parents('.grid').children( '.entry__featured-image'); 
        } 
       return $featuredImage;
    }