Javascript - mouseover/out 事件同时在所有兄弟元素上触发
Javascript - mouseover/out event fires on all sibling elements at the same time
我有四个 class 为 "box" 的兄弟元素。我使用带有 for 循环的 getElementsByClassName()
来迭代匹配的元素集,并使用 addEventListener()
方法将 mouseover
事件绑定到每个元素。
我遇到的问题 是当我在事件处理程序中使用 .style.display
并将鼠标悬停在任何匹配元素上时,所有前面的兄弟匹配元素更改它们的显示值。
如果我使用 .style.backgroundColor
等不同的样式方法,一切正常。我用 google 和 youtubed 搜索过,但找不到解决方案。我将不胜感激任何帮助,谢谢。
代码:
function hover(eClass) {
var elem = document.getElementsByClassName(eClass);
for (var i=0;i<elem.length;i++) {
elem[i].addEventListener('mouseover', mouseOver);
elem[i].addEventListener('mouseout', mouseOut);
}
function mouseOver() {
//this.style.backgroundColor = 'red';
this.style.display = 'none';
}
function mouseOut() {
//this.style.backgroundColor = 'grey';
}
}
hover('box');
我检查了你的代码。没关系。事实上,如果您尝试将鼠标悬停在最后一个(底部)方块上,它只会消失。当您将鼠标悬停在最上面的一个时,它会消失,下一个会成为最上面的一个,所以它也会消失,依此类推,直到所有的消失。这发生得太快了,所有的方块都立刻消失了……
这很有趣,过了一段时间才发现这只是一个实际问题。当您将鼠标悬停在第一个框上时,它会被移除,而下一个框会在其位置重新绘制。但是随后该事件在方框 2 上再次触发,因为 it 现在位于光标下方,因此它会继续。当然,这发生得太快了,看不到,但这就是正在发生的事情。如果您真的想从浏览器的绘制功能中删除该元素,则必须想办法停止在下一个元素上触发事件,或者设置 opacity: 0.
更新
这有点丑陋,但是删除事件侦听器并再次添加它们演示了可以如何工作。 http://codepen.io/dannyjolie/pen/mPmpqE
function mouseOver() {
//this.style.backgroundColor = 'red';
removeListeners('box');
this.style.display = 'none';
setTimeout(function(){
addListeners('box');
}, 100);
}
misher
打败了我,但是是的,这就是正在发生的事情。我把 1 - 4 放在 DIV
s:
<div class="container">
<div class="box grey">1</div>
<div class="box grey">2</div>
<div class="box grey">3</div>
<div class="box grey">4</div>
</div>
并使用 console
捕捉元素的 innerHTML
并且它们消失了,这给了我:
1
2
3
4
毫不奇怪,一旦 display
设置为 none
,元素就会向上移动,因为您悬停的元素不再有 CSS 发挥作用。您可以使用 visibility
来防止这种情况发生,但是 mouseout
事件不会在不可见元素上触发。
稍微调整一下,您可以使用 data
属性和 mousemove
事件来保持元素的位置;这只会触发一次,因此如果页面调整大小或移动 X 和 Y 值将关闭,也许 window.onresize
可以解决这个问题,但这里是:
function hover(eClass) {
var elem = document.getElementsByClassName(eClass);
for (var i = 0; i < elem.length; i++) {
elem[i].addEventListener('mouseover', mouseOver);
}
document.addEventListener('mousemove', mouseMove);
function mouseOver() {
var minX = this.offsetLeft;
var maxX = minX + this.offsetWidth;
var minY = this.offsetTop;
var maxY = minY + this.offsetHeight;
this.setAttribute('data-minx', minX);
this.setAttribute('data-maxx', maxX);
this.setAttribute('data-miny', minY);
this.setAttribute('data-maxy', maxY);
this.style.visibility = 'hidden';
}
function mouseMove(e) {
e = e || event;
for(i = 0; i < elem.length; i++) {
var div = elem[i];
var minX = div.getAttribute('data-minx');
var maxX = div.getAttribute('data-maxx');
var minY = div.getAttribute('data-miny');
var maxY = div.getAttribute('data-maxy');
if(e.clientX >= minX && e.clientX <= maxX && e.clientY >= minY && e.clientY <= maxY) {
// over the Div
} else {
div.style.visibility = 'visible';
}
}
}
}
hover('box');
我有四个 class 为 "box" 的兄弟元素。我使用带有 for 循环的 getElementsByClassName()
来迭代匹配的元素集,并使用 addEventListener()
方法将 mouseover
事件绑定到每个元素。
我遇到的问题 是当我在事件处理程序中使用 .style.display
并将鼠标悬停在任何匹配元素上时,所有前面的兄弟匹配元素更改它们的显示值。
如果我使用 .style.backgroundColor
等不同的样式方法,一切正常。我用 google 和 youtubed 搜索过,但找不到解决方案。我将不胜感激任何帮助,谢谢。
代码:
function hover(eClass) {
var elem = document.getElementsByClassName(eClass);
for (var i=0;i<elem.length;i++) {
elem[i].addEventListener('mouseover', mouseOver);
elem[i].addEventListener('mouseout', mouseOut);
}
function mouseOver() {
//this.style.backgroundColor = 'red';
this.style.display = 'none';
}
function mouseOut() {
//this.style.backgroundColor = 'grey';
}
}
hover('box');
我检查了你的代码。没关系。事实上,如果您尝试将鼠标悬停在最后一个(底部)方块上,它只会消失。当您将鼠标悬停在最上面的一个时,它会消失,下一个会成为最上面的一个,所以它也会消失,依此类推,直到所有的消失。这发生得太快了,所有的方块都立刻消失了……
这很有趣,过了一段时间才发现这只是一个实际问题。当您将鼠标悬停在第一个框上时,它会被移除,而下一个框会在其位置重新绘制。但是随后该事件在方框 2 上再次触发,因为 it 现在位于光标下方,因此它会继续。当然,这发生得太快了,看不到,但这就是正在发生的事情。如果您真的想从浏览器的绘制功能中删除该元素,则必须想办法停止在下一个元素上触发事件,或者设置 opacity: 0.
更新
这有点丑陋,但是删除事件侦听器并再次添加它们演示了可以如何工作。 http://codepen.io/dannyjolie/pen/mPmpqE
function mouseOver() {
//this.style.backgroundColor = 'red';
removeListeners('box');
this.style.display = 'none';
setTimeout(function(){
addListeners('box');
}, 100);
}
misher
打败了我,但是是的,这就是正在发生的事情。我把 1 - 4 放在 DIV
s:
<div class="container">
<div class="box grey">1</div>
<div class="box grey">2</div>
<div class="box grey">3</div>
<div class="box grey">4</div>
</div>
并使用 console
捕捉元素的 innerHTML
并且它们消失了,这给了我:
1
2
3
4
毫不奇怪,一旦 display
设置为 none
,元素就会向上移动,因为您悬停的元素不再有 CSS 发挥作用。您可以使用 visibility
来防止这种情况发生,但是 mouseout
事件不会在不可见元素上触发。
稍微调整一下,您可以使用 data
属性和 mousemove
事件来保持元素的位置;这只会触发一次,因此如果页面调整大小或移动 X 和 Y 值将关闭,也许 window.onresize
可以解决这个问题,但这里是:
function hover(eClass) {
var elem = document.getElementsByClassName(eClass);
for (var i = 0; i < elem.length; i++) {
elem[i].addEventListener('mouseover', mouseOver);
}
document.addEventListener('mousemove', mouseMove);
function mouseOver() {
var minX = this.offsetLeft;
var maxX = minX + this.offsetWidth;
var minY = this.offsetTop;
var maxY = minY + this.offsetHeight;
this.setAttribute('data-minx', minX);
this.setAttribute('data-maxx', maxX);
this.setAttribute('data-miny', minY);
this.setAttribute('data-maxy', maxY);
this.style.visibility = 'hidden';
}
function mouseMove(e) {
e = e || event;
for(i = 0; i < elem.length; i++) {
var div = elem[i];
var minX = div.getAttribute('data-minx');
var maxX = div.getAttribute('data-maxx');
var minY = div.getAttribute('data-miny');
var maxY = div.getAttribute('data-maxy');
if(e.clientX >= minX && e.clientX <= maxX && e.clientY >= minY && e.clientY <= maxY) {
// over the Div
} else {
div.style.visibility = 'visible';
}
}
}
}
hover('box');