Paul Thompson
Paul Thompson

Reputation: 123

Display div on hover and mouseenter but hide when mouse is not on target or div

I have an issue where when hovering over a link it displays a div and then when hovering over the div it stays open.

But if I hover over the link and then move the mouse over another section of the page (not the div), the div remains open when it should close and only closes when the mouseleave event is fired when I move the mouse over the div and then off the div.

Can anyone help with this issue?

$(document).ready(function() {
  $(".showProducts").hide();

  $("#Shop").hover(function() {
      $("#productList ").show();
    }),
    $(".showProducts").mouseenter(function() {
      $("#productList ").show();
    });
  $(".showProducts").mouseleave(function() {
    $(" #productList").hide();
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="Shop" name="Shop" class="nav-link" href="/shop/">Shop</a>

<div id="productList" class="container showProducts">productList</div>

Upvotes: 2

Views: 2785

Answers (4)

Nolwac
Nolwac

Reputation: 31

I think I understand what you are trying to do. What you can do to solve the problem is to listen for both a hover over event and a mouse leave event on the link. The hover event will take care of making sure that the div gets shown when the mouse goes over the link and then the mouse leave event will make sure that the div disappears when the mouse leaves the link but of course you will as well listen for both a hover over event and a mouse leave event on the div itself, the hover over event will make sure that the div is still being show while the mouse leave event will make sure that the div disappears once the mouse leaves it.

//add this to the original code
$("#Shop").mouseleave(function () {
        $("#productList ").hide();
}),

Upvotes: 0

Travis J
Travis J

Reputation: 82337

I would suggest using a technique called "debouncing" for this. Basically it just introduces a small timer for removing the visible field. Every time the mouse enters one of the areas, clear the timer. When it leaves, start it. At the conclusion of the timer, remove the content.

I added a fadeOut for effect, since you have extra time. The 450 millisecond delay is based on average mouse movements from users. The background colors are just so that it is clearer where exactly the content area we are looking at is.

$(document).ready(function() {
  $(".showProducts").hide();
  
  var timer;
  function debounce(){
      clearTimeout(timer);
      timer = setTimeout(function(){
          $("#productList").fadeOut('fast');
      },450);
  }
  
  $("#Shop").hover(function() {
      // hover over
      $("#productList").show();
      clearTimeout(timer);
    },function(){
      // hover out
      debounce();
    });
  $(".showProducts").mouseenter(function(){
    clearTimeout(timer);
  });
  $(".showProducts").mouseleave(function(){
    debounce();
  });
});
#Shop{
 background-color: lightgrey;
}

#productList{
 background-color: beige;
 width:50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<a id="Shop" name="Shop" class="nav-link" href="/shop/">Shop</a>

<div id="productList" class="container showProducts">productList</div>

Upvotes: 4

gavgrif
gavgrif

Reputation: 15509

You do not need jQuery for this - CSS can do it with the sibling combinator (you can use either the direct sibling combinator (+) to target the next element or the general sibiling combinator (~) if you have multiple siblings of the element.

#productList {display: none}
#Shop:hover + #productList {display: block}
#productList:hover {display: block}
<a id="Shop" name="Shop" class="nav-link" href="/shop/">Shop</a>

<div id="productList" class="container showProducts">productList</div>

Upvotes: 0

Steve0
Steve0

Reputation: 2253

How about a pure CSS solution? This one uses the next (+) selector...

a,
div {
  border: 1px solid red;
}

.showProducts {
  display: none;
}

#Shop:hover+div.showProducts {
  display: block;
}

div.showProducts:hover {
  display: block;
}
<a id="Shop" name="Shop" class="nav-link" href="/shop/">Shop</a>

<div id="productList" class="container showProducts">productList</div>

Upvotes: 1

Related Questions