ConorReidd
ConorReidd

Reputation: 276

jQuery - Stop child hover triggering parent click with relative elements

This is not a duplicate question. I've looked around stackoverflow and none of the following questions have worked for me.

jQuery stop child elements animate on hover of parent
How to have click event ONLY fire on parent DIV, not children?

I have a parent element .cover and a single child element inside called .details-wrapper

When i hover over the child element of the parent, the parent hover is being triggered. This is how i want it to be (Sorry about editing);

enter image description here

Currently what i have tried (And failed) is using return false; and stopPropagation

The image has position: relative and top: 160px so it comes out of the original .cover wrapper

It's really weird because the way i hover ovre the element determines how the jquery works. Here's a gif showing that.

https://gyazo.com/7153f3b8d3a57d0cfbb6b8d7d56caf0a

The jQuery i'm using is:

$(".cover").not('.details-wrapper').hover(function(e) {
    if (e.target === this) {
        $(".cover").css("background","url(url1), url('"+cover._url+"')");
    }
}, function() {
    $(".cover").css("background","url('"+cover._url+"')");
});

I'm unsure how I can fix this so when i hover over the child element it stops the hover for the parent from triggering.

Just for further clarity, this doesnt work either:

$(".cover").hover(function(e) {
    if (e.target === this) {
        $(".cover").css("background","url(url1), url('"+cover._url+"')");
    }
}, function() {
    $(".cover").css("background","url('"+cover._url+"')");
});

$(".cover .details-wrapper").hover(function(e) {
    e.stopPropagation();
});

Upvotes: 1

Views: 2086

Answers (1)

Terry
Terry

Reputation: 66093

Don't rely on the .hover() function, which is a shorthand for the .mouseenter() and .mouseleave() events. You need the .mouseover() and .mouseout() events, and it will trigger appropriately when entering/leaving child nodes:

$(function() {
  $('.cover').on('mouseover', function(e) {
      if (e.target === this) {
        $('.cover').css('background','url(url1), url(''+cover._url+'')');
      }
    })
    .on('mouseout', function() {
       $('.cover').css('background','url(''+cover._url+'')');
    });
});

The simple explanation is this: when you are using .hover() (hence the mouseenter and mouseleave were being listened), they are not triggered when you enter or leave the child elements. This causes the event to appear to be "propagated" because in the background, the mouseleave event was never called when you enter the child. However, the mouseout event will be called, resulting in the desired behaviour.

Here is a proof-of-concept example (using a red background to indicate mouseover events):

$(function() {
  $('.cover').on('mouseover', function(e) {
      if (e.target === this) {
        $('.cover').css('background', 'red');
      }
    })
    .on('mouseout', function() {
      $('.cover').css('background', 'transparent');
    });
});
* {
  padding: 0;
  margin: 0;
}
.cover {
  padding: 2rem;
  text-align: center;
  position: relative;
  height: 10rem;
}
.cover .details-wrapper {
  background-color: #eee;
  position: absolute;
  top: 50%;
  left: 50%;
  padding: 2rem;
  transform: translate(-50%,-50%);
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cover">
  Cover
  <div class="details-wrapper">
    Details wrapper
  </div>
</div>

There is a thread on SO that discusses the difference between these events: Jquery mouseenter() vs mouseover()

Upvotes: 2

Related Questions