Refresh the browser hover effect after a DOM chang

2019-06-22 14:24发布

问题:

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.

回答1:

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.



回答2:

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



回答3:

element.parentNode.replaceChild(element, element);