我有这个HTML。我只想将mouseover和mouseleave事件附加到.parent
元素上,但是由于某些原因,它们也附加到children元素上,所以我的行为很奇怪。
<div class="parent">
<div class="child-1"></div>
<div class="child-2"></div>
</div>
这是我的方法
const parent = document.getElementsByClassName('parent')[0]
parent.addEventListener('mouseover', eventHandler)
parent.addEventListener('mouseleave', eventHandler)
发生了什么事以及如何预防?
答案 0 :(得分:1)
您必须将事件添加到子节点并取消事件的传播。
const parent = document.getElementsByClassName('parent')[0]
parent.addEventListener('mouseover', eventHandler)
parent.addEventListener('mouseleave', eventHandler)
for (const child of parent.childNodes) {
child.addEventListener('mouseover', function(event) {
event.stopPropagation();
})
child.addEventListener('mouseleave', function(event) {
event.stopPropagation();
})
}
function eventHandler() {
console.log('hey');
}
<div class="parent" style="width: 25px; height: 25px; background: red; padding: 50px">
<div class="child-1" style="width: 25px; height: 25px; background: blue"></div>
<div class="child-2" style="width: 25px; height: 25px; background: green"></div>
</div>
或者您可以做每个人想要的pointer-event
const parent = document.getElementsByClassName('parent')[0]
parent.addEventListener('mouseover', eventHandler)
parent.addEventListener('mouseleave', eventHandler)
for (const child of parent.childNodes) {
child.className += ' no-event'
}
function eventHandler() {
console.log('hey');
}
.no-event {
pointer-events: none;
}
<div class="parent" style="width: 25px; height: 25px; background: red; padding: 50px">
<div class="child-1" style="width: 25px; height: 25px; background: blue"></div>
<div class="child-2" style="width: 25px; height: 25px; background: green"></div>
</div>
答案 1 :(得分:0)
它必须完成事件捕获和冒泡的工作方式。我复制了@ACD答案,以查看它的行为是否有所不同。如果您注意到我们是否将鼠标悬停在孩子上并移到父对象上,则在此示例中未调用该事件。因此,子元素不再是事件的目标。
该活动分为捕捉和冒泡两个阶段。您可以找到更多信息here。该事件是为孩子触发的,它正在冒泡给父事件。您可以通过event.target
如果我们删除pointer-events: none;
,则目标是孩子而不是父母。并在调用子处理程序后将通风口传播到父级,然后调用父级回调。
const parent = document.getElementsByClassName('parent')[0]
parent.addEventListener('mouseover', eventHandler)
parent.addEventListener('mouseleave', eventHandler)
function eventHandler(e) {
console.log(e.target, 'hey');
}
<div class="parent" style="width: 25px; height: 25px; background: red; padding: 50px">
<div class="child-1" style="pointer-events: none; width: 25px; height: 25px; background: blue"></div>
<div class="child-2" style="pointer-events: none; width: 25px; height: 25px; background: green"></div>
</div>
答案 2 :(得分:-1)
尝试使用mouseenter
和mouseleave
而不是mouseover
和mouseleave
。不要把它们混在一起。这是mouseover/mouseout
或mouseenter/mouseleave
的组合,因为这些组合是对称的。
https://developer.mozilla.org/en-US/docs/Web/Events/mouseenter
var logs = document.querySelector('.log');
var area = document.querySelector('.parent');
function eventHandler (e) {
if (e.type === 'mouseenter') {
area.style.backgroundColor = '#c00';
} else {
area.style.backgroundColor = '';
}
}
area.addEventListener('mouseenter', eventHandler);
area.addEventListener('mouseleave', eventHandler);
.parent {
background: #eee;
}
.child {
padding: 30px 20px;
}
.child + .child {
border-top: 1px dotted #333;
}
<div class="parent">
<div class="child">
foo bar baz
</div>
<div class="child">
foo bar baz
</div>
</div>
答案 3 :(得分:-1)
您可以通过应用
使用CSS解决此问题.child-1, .child-2 {
pointer-events: none
}
对于孩子们,那样就不可能与孩子们互动。
或者,您可以在事件处理程序中检查event.target
是父节点还是子节点,将鼠标悬停在子节点上将产生子节点,将鼠标悬停在.parent
上将产生父节点。