I've got an element whose css is altered under :hover
. I've also got some javascript that changes the height of the element. However if the javascript fires while the :hover
state is active the state remains even though the height change moves the element out from underneath the mouse.
Also since the javascript is fired by a click event within the element. This effect occurs on touch screens too.
I want to know if there's some way of coping with this issue. Can I force the browser to re-calculate hover (or mouseover etc)? Looking at this question, I'm not optimistic.
I've created a fiddle to demonstrate the issue.
I guess if the worst comes to the worst I could do it all manually with classes, mouseenter
, mouseleave
and DOMAttrModified
. But that sounds like a pain and may even be costly in terms of javascript (I'll have to manually identify whether the mouse sits within the bounds of my elements).
UPDATE
OK, so I really can't touch DOMAttrModified
, the performance hit is massive.
The mouseleave
event is never firing if you just leave your cursor there because technically you're not leaving the div that has the hover state.
I would recommend not using mouseover
. It's a pain. Use mouseenter
instead.
I do not know of any viable solutions, other than working around it by testing if the div is in it's :hover
state, and then creating a separate function with a timeout to return it to it's original position, size, etc.
I am not sure at all if this is viable in a real-life scenario, but this is only hack I could see. Basically on window.mouseMove
event save current coordinates of the mouse and then on setInterval
compare it to coordinates of the element to determine whether element is "hovered". I have to use setInterval because otherwise unless mouse moves - no event happens:
var el = document.getElementById('el');
var mouseX, mouseY;
window.onmousemove=function(event){
ev = event || window.event;
mouseX = ev.pageX;
mouseY = ev.pageY;
}
setInterval(function() {
if (mouseX >=el.offsetLeft && mouseX <= el.offsetLeft + el.offsetWidth &&
mouseY >=el.offsetTop && mouseX <= el.offsetTop + el.offsetHeight) {
el.style.top = '200px';
el.style.left = '200px';
el.className = 'div_hover';
} else {
el.style.top = '50px';
el.style.left = '50px';
el.className = '';
}
},1000)
I've used 1000 interval to demonstrate the effect (demo) this can be adjusted. But again, I am not sure how feasible is pulling this info on setInterval
element.parentNode.replaceChild(element, element);