Preventing Hover event of a Div triggering on parent Div?
By definition, hovering over a child, hovers over the parent as well. There is no "blocking" in html events.
There are two method chains, the bubble and the capture.
Any event taking place in the W3C event model is first captured until
it reaches the target element and then bubbles up again.
http://www.quirksmode.org/js/events_order.html
The only way you're going to stop this is to prevent the bubbling by adding javascript to your page to prevent the chain. This is simple in jQuery
$('.mensal').hover(function(e){
e.stopPropagation();
});
It occurs to me that this answer is completely unhelpful when dealing with CSS. Javascript events dont deal with CSS selectors or preventing them.
Unfortunately, with CSS alone, I do not know of a way to accomplish this (and even in javascript it can get tricky). CSS 4 selectors will allow you to specify the subject of the selector http://dev.w3.org/csswg/selectors4/#subject so that you can do something like
#operaContent .opera:hover! .mensal:not(:hover) { /*your css*/ }
but this isnt implemented yet, and is still under development for the draft.
EDIT:
Here is a javascript (jQuery) implementation that should work for you
$(function(){
$('.opera').hover(function() {$(this).addClass('hoverIntent')},
function(){ $(this).removeClass('hoverIntent'); }
);
$('.opera .mensal').hover(function() {
$(this).parent('.opera').removeClass('hoverIntent');
});
})
and the modified CSS
#operaContent {
padding: 0 50px 0 50px;
position: relative;
overflow: visible;
}
#operaContent .opera {
display: block;
border: 1px solid #FFFFFF;
border-bottom: 1px solid #DDDDDD;
padding: 5px;
margin-bottom: 10px;
height: 120px;
background-color: #0A8ECC;
}
#operaContent .opera.hoverIntent {
border: 1px solid #AAAAAA;
background-color: #DDDDDD;
cursor: pointer;
}
.mensal {
position: absolute;
top: 1px;
left: 8px;
z-index: 3;
display: block;
}
and the obligitory working demo: http://jsfiddle.net/WB6Ty/
Prevent particular child element from firing parent's mouseover event in jQuery
check whether child-description is the target of the event
$('.main-parent').mouseenter(function (e) {
if (!$(e.target).hasClass('child-description')) {
$(this).addClass('item-hovered');
}
}).mouseleave(function () {
$(this).removeClass('item-hovered');
});
jQuery - Stop child hover triggering parent click with relative elements
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>
Prevent onmouseout when hovering child element of the parent absolute div WITHOUT jQuery
function onMouseOut(event) {
//this is the original element the event handler was assigned to
var e = event.toElement || event.relatedTarget;
if (e.parentNode == this || e == this) {
return;
}
alert('MouseOut');
// handle mouse event here!
}
document.getElementById('parent').addEventListener('mouseout',onMouseOut,true);
I made a quick JsFiddle demo, with all the CSS and HTML needed, check it out...
EDIT FIXED link for cross-browser support http://jsfiddle.net/RH3tA/9/
NOTE that this only checks the immediate parent, if the parent div had nested children then you have to somehow traverse through the elements parents looking for the "Orginal element"
EDIT example for nested children
EDIT Fixed for hopefully cross-browser
function makeMouseOutFn(elem){
var list = traverseChildren(elem);
return function onMouseOut(event) {
var e = event.toElement || event.relatedTarget;
if (!!~list.indexOf(e)) {
return;
}
alert('MouseOut');
// handle mouse event here!
};
}
//using closure to cache all child elements
var parent = document.getElementById("parent");
parent.addEventListener('mouseout',makeMouseOutFn(parent),true);
//quick and dirty DFS children traversal,
function traverseChildren(elem){
var children = [];
var q = [];
q.push(elem);
while (q.length > 0) {
var elem = q.pop();
children.push(elem);
pushAll(elem.children);
}
function pushAll(elemArray){
for(var i=0; i < elemArray.length; i++) {
q.push(elemArray[i]);
}
}
return children;
}
And a new JSFiddle, EDIT updated link
How do I prevent a parent's onclick event from firing when a child anchor is clicked?
Events bubble to the highest point in the DOM at which a click event has been attached. So in your example, even if you didn't have any other explicitly clickable elements in the div, every child element of the div would bubble their click event up the DOM to until the DIV's click event handler catches it.
There are two solutions to this is to check to see who actually originated the event. jQuery passes an eventargs object along with the event:
$("#clickable").click(function(e) {
var senderElement = e.target;
// Check if sender is the <div> element e.g.
// if($(e.target).is("div")) {
window.location = url;
return true;
});
You can also attach a click event handler to your links which tell them to stop event bubbling after their own handler executes:
$("#clickable a").click(function(e) {
// Do something
e.stopPropagation();
});
React how to prevent a parent's onclick event from firing when a child is clicked?
Well the obvious answer would be to put it outside of the div
.
But if you really can't, you can always use CSS for this.
Try using pointer-events
Example:
HTML -
<div
className={classes.container}
onClick={() => navigate(`${props.productName}`)}
>
<img src={props.image} alt="" />
<svg className='no-events'></svg>
</div>
CSS -
.no-events {
pointer-events: none;
}
Prevent :hover bubbling
If you set the children's pointer-events
to none
, you can achieve this without any JavaScript
.
#parent { background: green; width: 100px; height: 100px; position: relative; margin: 0 auto;}
#parent:hover { background: rgba(0, 0, 0, 0.8);}
#child-left { background: red; width: 50px; height: 50px; position: absolute; top: 0; left: -50px;}
#child-right { background: red; width: 50px; height: 50px; position: absolute; top: 50px; left: 100px;}
#child-left,#child-right { pointer-events: none;}
<div id="parent"> <div id="child-left"></div> <div id="child-right"></div></div>
Related Topics
Why Does Fixed Positioning Alter the Width of an Element
Change Background of Child If Parent :Hover
Wrap Text Around an Image on Bootstrap 3
Purgecss Whitelist Patterns with Tailwindcss
Draw Half Circle with CSS or Svg
CSS Select First Child Only If Two Children
Border-Radius Doesn't Work on Ie10
CSS Attribute Selector + Descendant Gives a Bug in Webkit
Give a CSS Styled Div a "Border-Left-Image"
CSS - How to Select Multiple Different Child Elements Within a Parent Without Repeating the Parent
Change Animation Speed on Hover
Responsive Design: Centralize a Full-Screen Square in Any Screen Size
Browser Handling of CSS "Transparent" in Gradients
How to Set Maximum Number of Rows in a Flexbox Container and Hide Extra Element