Reputation: 921
I have four sibling elements with a class of "box". I use the getElementsByClassName()
with a for loop to iterate over the matching set of elements and use the addEventListener()
method to bind a mouseover
event to each element.
The problem I am having is when I use .style.display
in the event handler, and mouse over any of the matching elements, all of the preceding sibling matching elements change their display values.
If I use a different style method like .style.backgroundColor
everything works fine. I have googled and youtubed and I can't find a solution. I would appreciate any and all assistance, thank you.
Code:
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');
Upvotes: 1
Views: 1339
Reputation: 1062
I checked your code. It's fine. In fact, ig you try to hover the last (at the bottom) square, only it will disappear. When you hover the top one, it disappears and next one become the top one, so it disappear too, and so on, until all them disappear. This happen too fast and it seams that all squares disappear at once...
Upvotes: 3
Reputation: 3224
misher
beat me to it, but yes that is what's happening. I put 1 - 4 in the 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>
And used the console
to catch the innerHTML
of the elements and they vanish, which gave me:
1
2
3
4
No surprise there, once the display
is set to none
, the elements move up as the one you hovered no longer has its CSS in play. You can use visibility
to keep that from happening, but the mouseout
event will not trigger on invisible elements.
With a bit of tweaking, you can use the data
attribute and the mousemove
event to keep the elements in place; this will only fire once so if the page re-sizes or moves the X and Y values will be off, perhaps a window.onresize
would fix that, but here's this:
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');
Upvotes: 1
Reputation: 11349
This was funny, and it took a while to see that it's just a practical problem. When you hover over the first box, it is removed, and the next one is redrawn in its place. But then the event fires again on box 2, because it is now below the cursor, and so it continues. Of course this happens too fast to see, but it's what's going on. If you really want to remove the element from the browser's draw function, you'll have to figure out something to stop the event firing on the next element, or set opacity: 0.
Update
This is sort of ugly, but removing the event listeners and adding them again demonstrates how this could work. http://codepen.io/dannyjolie/pen/mPmpqE
function mouseOver() {
//this.style.backgroundColor = 'red';
removeListeners('box');
this.style.display = 'none';
setTimeout(function(){
addListeners('box');
}, 100);
}
Upvotes: 2