2

How do I make this only fire :hover for the target element (ignoring the parents)?

Assume this is recursive design of object inside object, therefore with the same classes and an autogenerated id.

.group:hover {
  background-color: red;
}

.group {
  border: 1px solid black;
  width: 100px;
  padding: 20px;
}
<div id="g1" class="group">aaaa
  <div id="g2" class="group">bbbb
    <div id="g3" class="group">cccc
    </div>
  </div>
</div>
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63
Janine Rawnsley
  • 1,240
  • 2
  • 10
  • 20
  • also you can check there https://stackoverflow.com/questions/14792574/css-child-set-to-change-color-on-parent-hover-but-changes-also-when-hovered/14792701 – errorau Mar 26 '19 at 12:27
  • 1
    I don't think you can. Since `c` is structurally included in `a`, when you hover `c` you necessarily hover `a` too. – Jeremy Thille Mar 26 '19 at 12:30
  • I'm wondering if mouseout and mouseover could be used, or if they'd have the same issue (of parent being assumed to have a mouseover) – Janine Rawnsley Mar 26 '19 at 12:48

4 Answers4

4

Since you tagged the question with javascript you can achieve this using it. The key is to use .stopProgagation() which will stop events from "falling through" down to your other elements.

See example below:

document.querySelectorAll(".group").forEach(elem => {
  elem.addEventListener('mouseover', function(e) {
    e.stopPropagation();
    this.classList.add('group-hover');
  });
  
  elem.addEventListener('mouseout', function(e) {
    this.classList.remove('group-hover');
  });
});
.group-hover {
  background-color: red;
}

.group {
  border: 1px solid black;
  width: 100px;
  padding: 20px;
}
<div id="g1" class="group">aaaa
  <div id="g2" class="group">bbbb
    <div id="g3" class="group">cccc
    </div>
  </div>
</div>

Alternatively, you could intead use e.target to get the target of the event if you wish not to use stopPropagation():

document.querySelectorAll(".group").forEach(elem => {
  elem.addEventListener('mouseover', e => e.target.classList.add('group-hover'));
  elem.addEventListener('mouseout', e => e.target.classList.remove('group-hover'));
});
.group-hover {
  background-color: red;
}

.group {
  border: 1px solid black;
  width: 100px;
  padding: 20px;
}
<div id="g1" class="group">aaaa
  <div id="g2" class="group">bbbb
    <div id="g3" class="group">cccc
    </div>
  </div>
</div>
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
1

Only with JS, and using events delegate for simpler way

const All_g = document.querySelector('#g1');

All_g.onmouseover = function(event) {
  let target = event.target;
  target.style.background = 'red';
};

All_g.onmouseout = function(event) {
  let target = event.target;
  target.style.background = '';
};
.group {
  border: 1px solid black;
  width: 100px;
  padding: 20px;
}
<div id="g1" class="group">aaaa
  <div id="g2" class="group">bbbb
    <div id="g3" class="group">cccc
    </div>
  </div>
</div>

some explanations :=> https://javascript.info/mousemove-mouseover-mouseout-mouseenter-mouseleave

Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
0

You can do it in the following way:

var elements = document.getElementsByClassName('group');
var lastElement = null;
elements.each(element =>{
    lastElement = element;
});
lastElement.on('hover', function(){
    //do anything you wish with element
})
  • That wouldn't work if I e.g. hovered over g2 - in which case g2 should apply the hover style (and not g1). Unless you're saying we should run this code every time the mouse moves? – Janine Rawnsley Mar 26 '19 at 12:44
  • As far as I understand you only need hover effect on the last item, right? If yes, so attach the hover effect on document ready, and that'll will work – Davronbek Rahmonov Mar 26 '19 at 12:48
  • Nope, I need to hover on whatever is under the mouse, and not any parents. So in the above example, g1 OR g2 OR g3 depending which one the pointer is physically over. – Janine Rawnsley Mar 26 '19 at 12:55
0

Approach 1

Register hover event to toggle class and use event.stopPropagation();

https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

The bubbles read-only property of the Event interface indicates whether the event bubbles up through the DOM or not.

https://developer.mozilla.org/en-US/docs/Web/API/Event/bubbles

Approach 2

Mouseenter event - By design it does not bubble - so don't have to perform event.stopPropagation()

Though similar to mouseover, it differs in that it doesn't bubble and that it isn't sent to any descendants when the pointer is moved from one of its descendants' physical space to its own physical space.

https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseenter_event

takrishna
  • 4,884
  • 3
  • 18
  • 35