我在绝对定位的div中的onmouseout函数遇到了麻烦。当鼠标击中div中的子元素时,mouseout事件发生,但我不希望它发生,直到鼠标离开父元素,绝对div。
我如何防止mouseout事件从发射时,它击中一个子元素没有jquery。
我知道这与事件冒泡有关,但我没有找到如何解决这个问题的方法。
我在这里找到了一个类似的帖子:如何禁用由子元素触发的鼠标退出事件?
但是,该解决方案使用jQuery。
我在绝对定位的div中的onmouseout函数遇到了麻烦。当鼠标击中div中的子元素时,mouseout事件发生,但我不希望它发生,直到鼠标离开父元素,绝对div。
我如何防止mouseout事件从发射时,它击中一个子元素没有jquery。
我知道这与事件冒泡有关,但我没有找到如何解决这个问题的方法。
我在这里找到了一个类似的帖子:如何禁用由子元素触发的鼠标退出事件?
但是,该解决方案使用jQuery。
当前回答
有两种方法可以处理这个问题。
1)检查事件。目标结果在你的回调,看看它是否匹配你的父div
var g_ParentDiv;
function OnMouseOut(event) {
if (event.target != g_ParentDiv) {
return;
}
// handle mouse event here!
};
window.onload = function() {
g_ParentDiv = document.getElementById("parentdiv");
g_ParentDiv.onmouseout = OnMouseOut;
};
<div id="parentdiv">
<img src="childimage.jpg" id="childimg" />
</div>
2)或者使用事件捕获和调用事件。回调函数中的stopPropagation
var g_ParentDiv;
function OnMouseOut(event) {
event.stopPropagation(); // don't let the event recurse into children
// handle mouse event here!
};
window.onload = function() {
g_ParentDiv = document.getElementById("parentdiv");
g_ParentDiv.addEventListener("mouseout", OnMouseOut, true); // pass true to enable event capturing so parent gets event callback before children
};
<div id="parentdiv">
<img src="childimage.jpg" id="childimg" />
</div>
其他回答
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);
我做了一个快速的JsFiddle演示,所有的CSS和HTML需要,检查它…
编辑固定链接跨浏览器支持http://jsfiddle.net/RH3tA/9/
注意,这只检查直接的父元素,如果父div有嵌套的子元素,那么你必须以某种方式遍历元素的父元素,寻找“原始元素”
编辑嵌套子的示例
编辑修复希望跨浏览器
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;
}
和一个新的JSFiddle, EDIT更新链接
有两种方法可以处理这个问题。
1)检查事件。目标结果在你的回调,看看它是否匹配你的父div
var g_ParentDiv;
function OnMouseOut(event) {
if (event.target != g_ParentDiv) {
return;
}
// handle mouse event here!
};
window.onload = function() {
g_ParentDiv = document.getElementById("parentdiv");
g_ParentDiv.onmouseout = OnMouseOut;
};
<div id="parentdiv">
<img src="childimage.jpg" id="childimg" />
</div>
2)或者使用事件捕获和调用事件。回调函数中的stopPropagation
var g_ParentDiv;
function OnMouseOut(event) {
event.stopPropagation(); // don't let the event recurse into children
// handle mouse event here!
};
window.onload = function() {
g_ParentDiv = document.getElementById("parentdiv");
g_ParentDiv.addEventListener("mouseout", OnMouseOut, true); // pass true to enable event capturing so parent gets event callback before children
};
<div id="parentdiv">
<img src="childimage.jpg" id="childimg" />
</div>
香草也可以用这种方法
document.querySelector('.product_items') && document.querySelector('.product_items').addEventListener('mouseleave', () => updateCart()) const updateCart = () => { let total = 0; document.querySelectorAll('input') && document.querySelectorAll('input').forEach(item => total += +item.value) document.getElementById('total').innerHTML = total } <div class="product_items"> <div class="product_item"> <div class="product_name"> </div> <div class="multiply__btn"> <button type="button">-</button> <input name="test" type="text"> <button type="button">+</button> </div> </div> <div class="product_item"> <div class="product_name"> </div> <div class="multiply__btn"> <button type="button">-</button> <input name="test" type="text"> <button type="button">+</button> </div> </div> <div class="product_item"> <div class="product_name"> </div> <div class="multiply__btn"> <button type="button">-</button> <input name="test" type="text"> <button type="button">+</button> </div> </div> </div> <div id="total"></div>
在Angular 5、6和7上
<div (mouseout)="onMouseOut($event)"
(mouseenter)="onMouseEnter($event)"></div>
然后在
import {Component,Renderer2} from '@angular/core';
...
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent implements OnInit, OnDestroy {
...
public targetElement: HTMLElement;
constructor(private _renderer: Renderer2) {
}
ngOnInit(): void {
}
ngOnDestroy(): void {
//Maybe reset the targetElement
}
public onMouseEnter(event): void {
this.targetElement = event.target || event.srcElement;
console.log('Mouse Enter', this.targetElement);
}
public onMouseOut(event): void {
const elementRelated = event.toElement || event.relatedTarget;
if (this.targetElement.contains(elementRelated)) {
return;
}
console.log('Mouse Out');
}
}
感谢阿姆贾德·马萨德,他激励了我。
我有以下解决方案,似乎在IE9, FF和Chrome和代码很短(没有复杂的闭包和横向子东西):
DIV.onmouseout=function(e){
// check and loop relatedTarget.parentNode
// ignore event triggered mouse overing any child element or leaving itself
var obj=e.relatedTarget;
while(obj!=null){
if(obj==this){
return;
}
obj=obj.parentNode;
}
// now perform the actual action you want to do only when mouse is leaving the DIV
}