skip to Main Content

Here is a simple html+css+js code

var myDiv = document.getElementById('myDiv');

myDiv.addEventListener('mouseenter', function() {
  console.log('Mouse entered the div');
});

myDiv.addEventListener('mouseleave', function() {
  console.log('Unfortunately this message happens when we enter the smaller div');
});
#myDiv {
  width: 300px;
  height: 300px;
  background-color: yellow;
  position: absolute;
}
#smaller {
  border: 1px solid red;
  width: 100px;
  height: 100px;
  position: absolute;
  top: 100px;
  left: 100px;
}
<div>
  <div id="myDiv"></div>
  <div id="smaller">
    
  </div>
</div>

The issue here is mouseleave triggers when the mouse appears above the second element. Any nice and simple solution to avoid that? Tried another events. No luck.

P.S. JS solution is preferable. CSS hover is not the way to go for my case.
The important note – divs are on the same level (the second div is not a child of the first div).

4

Answers


  1. Nest the #smaller div inside of the #myDiv div to fix the issue.

    Place the #smaller div inside of the #myDiv. This counts the smaller div as part of the #myDiv div and doesn’t trigger your mouseleave event listener. This shouldn’t mess with your structure since the #smaller div is already utilizing position: absolute;.

    var myDiv = document.getElementById('myDiv');
    
    myDiv.addEventListener('mouseenter', function() {
      console.log('Mouse entered the div');
    });
    
    myDiv.addEventListener('mouseleave', function() {
      console.log('Unfortunately this message happens when we enter the smaller div');
    });
    #myDiv {
      width: 300px;
      height: 300px;
      background-color: yellow;
      position: absolute;
    }
    #smaller {
      border: 1px solid red;
      width: 100px;
      height: 100px;
      position: absolute;
      top: 100px;
      left: 100px;
    }
    <div>
      <div id="myDiv"><div id="smaller"></div>
      </div>
    </div>
    Login or Signup to reply.
  2. If you want to keep the HTML structure as it is you can put a pointer-events: none; on the smaller element.

    var myDiv = document.getElementById('myDiv');
    
    myDiv.addEventListener('mouseenter', function() {
      console.log('Mouse entered the div');
    });
    
    myDiv.addEventListener('mouseleave', function() {
      console.log('Unfortunately this message happens when we enter the smaller div');
    });
    #myDiv {
      width: 300px;
      height: 300px;
      background-color: yellow;
      position: absolute;
    }
    
    #smaller {
      border: 1px solid red;
      width: 100px;
      height: 100px;
      position: absolute;
      top: 100px;
      left: 100px;
      pointer-events: none;
    }
    <div>
      <div id="myDiv"></div>
      <div id="smaller">
    
      </div>
    </div>
    Login or Signup to reply.
  3. The way you describe it just put the event on the containing element and you are good to go.

    const container = document.querySelector('.div-container');
    
    container.addEventListener('mouseenter', function() {
      console.log('Mouse entered the div');
    });
    
    container.addEventListener('mouseleave', function() {
      console.log('Unfortunately this message happens when we enter the smaller div');
    });
    #myDiv {
      width: 300px;
      height: 300px;
      background-color: yellow;
      position: absolute;
    }
    
    #smaller {
      border: 1px solid red;
      width: 100px;
      height: 100px;
      position: absolute;
      top: 100px;
      left: 100px;
    }
    <div class="div-container">
      <div id="myDiv"></div>
      <div id="smaller">
      </div>
    </div>
    Login or Signup to reply.
  4. One option is to use relatedTarget and a control flag to check if you were entering the smaller div(s).

    var myDiv = document.getElementById('myDiv');
    var inSmall = false;
    
    myDiv.addEventListener('mouseenter', function() {
      if (inSmall) {
        inSmall = false;
        return;
      }
      console.log('Mouse entered the div');
    });
    myDiv.addEventListener('mouseleave', function(e) {
      if (e.relatedTarget.id === 'smaller') {
        inSmall = true;
        return;
      }
      console.log('Unfortunately this message happens when we enter the smaller div');
    });
    #myDiv {
      width: 300px;
      height: 300px;
      background-color: yellow;
      position: absolute;
    }
    
    #smaller {
      border: 1px solid red;
      width: 100px;
      height: 100px;
      position: absolute;
      top: 100px;
      left: 100px;
    }
    <div>
      <div id="myDiv"></div>
      <div id="smaller">
      </div>
    </div>

    If you want mouseenter to trigger again when entering from the smaller div, you can remove the control flag.

    var myDiv = document.getElementById('myDiv');
    
    myDiv.addEventListener('mouseenter', function() {
      console.log('Mouse entered the div');
    });
    myDiv.addEventListener('mouseleave', function(e) {
      if (e.relatedTarget.id === 'smaller') return;
      console.log('Unfortunately this message happens when we enter the smaller div');
    });
    #myDiv {
      width: 300px;
      height: 300px;
      background-color: yellow;
      position: absolute;
    }
    
    #smaller {
      border: 1px solid red;
      width: 100px;
      height: 100px;
      position: absolute;
      top: 100px;
      left: 100px;
    }
    <div>
      <div id="myDiv"></div>
      <div id="smaller">
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search