Search code examples
javascriptjqueryevent-handlingmouseentermouseleave

How to target specific elements after mouseenter event?


I have this JS:

$(".play").mouseenter(function() {

    $( ".glitch-img" ).mgGlitch({
        // set 'true' to stop the plugin
        destroy : false, 
        // set 'false' to stop glitching
        glitch: true, 
        // set 'false' to stop scaling
        scale: true, 
        // set 'false' to stop glitch blending
        blend : true, 
        // select blend mode type
        blendModeType : 'hue',
        // set min time for glitch 1 elem
        glitch1TimeMin : 200, 
        // set max time for glitch 1 elem
        glitch1TimeMax : 400,
        // set min time for glitch 2 elem
        glitch2TimeMin : 10, 
        // set max time for glitch 2 elem
        glitch2TimeMax : 100, 
    });

}).mouseleave(function() {

    $( ".glitch-img" ).mgGlitch({
        destroy : true, // set 'true' to stop the plugin
    });

});

And my HTML is like this:

<div>
    <figure>
        <div class="glitch-img" style="background-image: url('assets/images/image.jpg')"></div>
    </figure>
</div>
<div>
    <div class="play play1"></div>
</div>

I don't know how to make my mouseenter work just on the current .play-element without affecting all the other .play-elements.


Solution

  • If I get you right you actually want to target the .glitch-img-element which you can target like showen below (I also refactorized your code):

    handleGlitch = function( oEvent )
    {
      // build the right configuration based on mouseenter/mouseleave
      oGlitch = oEvent.handleObj.origType == 'mouseleave'
      ? { destroy       : true } // config for "mouseleave"
      : { destroy       : false, // config for "mouseenter"
          glitch        : true, 
          scale         : true, 
          blend         : true, 
          blendModeType : 'hue',
          glitch1TimeMin: 200, 
          glitch1TimeMax: 400,
          glitch2TimeMin: 10, 
          glitch2TimeMax: 100 };
    
      // lets first get the element that triggered the event which is "div.play"
      // oEvent.target is the dom element on which the mouseenter/mouseleave event was fired
      $Play = $( oEvent.target ); // you can now do eg: $Play.addClass('active')|$Play.removeClass('active')
    
      // so now we have to target the right "div.glitch-img"
      // and not every "div.glitch-img" like it was before
      $Play
        .parent()            // get parent element of "div.play"
        .prev()              // get the previous element of that parent
        .find('.glitch-img') // now find the element with class "glitch-img"
        .mgGlitch( oGlitch ) // and do your glitchi stuff
    }
    
    // attache event handlers
    // event object will be passed as an argument to handleGlitch function
    $(".play").mouseenter( handleGlitch ).mouseleave( handleGlitch );
    <div>
      <figure>
        <div class="glitch-img" style="background-image: url('assets/images/image.jpg')"></div>
      </figure>
    </div>
    <div>
      <div class="play play1"></div>
    </div>
    
    <div>
      <figure>
        <div class="glitch-img" style="background-image: url('assets/images/image.jpg')"></div>
      </figure>
    </div>
    <div>
      <div class="play play2"></div>
    </div>


    Edit/Recommendation

    If you are able to I would strongly suggest to refactorize your markup. While my answer may helped you out with your current issue the

    $( oEvent.target ).parent().prev().find('.glitch-img')
    

    part will probably fail as soon as you just change an itty bitty on your current markup as it strongly relies on the structure of your markup which is a bad practice in general. So I would do something like:

    <div>
      <figure><!-- note the add of the id "glitch-1" which correspondents to "play-1" -->
        <div id="glitch-1" class="glitch-img" style="background-image: url('assets/images/image.jpg')"></div>
      </figure>
    </div>
    <div><!-- note the add of the id "play-1" which correspondents to "glitch-1" -->
      <div id="play-1" class="play"></div>
    </div>
    
    <div>
      <figure><!-- note the add of the id "glitch-2" which correspondents to "play-2" -->
        <div id="glitch-2" class="glitch-img" style="background-image: url('assets/images/image.jpg')"></div>
      </figure>
    </div>
    <div><!-- note the add of the id "play-2" which correspondents to "glitch-2" -->
      <div id="play-2" class="play"></div>
    </div>
    

    Now the structure of your markup is independent from the relation of #play-[nr] to #glitch-[nr] as long as you keep the pattern.

    handleGlitch = function( oEvent )
    {
      // now you can target your elements much more reliable and also more efficiently
      // lets get the number out of our "div.play" elment by its id
      sId = oEvent.target.id                   // eg: "play-1", "play-2"
      sNr = sId.substr( 1 + sId.indexOf('-') ) // eg: "1", "2"
    
      // now its easy to target the glitch element with vanilla JS
      document.getElementById( 'glitch-' + sNr )
      // but while you want to do some jQuery-mgGlitch-stuff you can do so by
      $( '#glitch-' + sNr ).mgGlitch( oGlitch )
    }
    
    $(".play").mouseenter( handleGlitch ).mouseleave( handleGlitch );
    

    Or with other words: you can now change your markup as you like without touching the JavaScript part anymore which is a very good thing. Isn't it?