简体   繁体   中英

Why does Firefox fire a mouseenter event on page load?

When hovering over an element and then refreshing the page (without moving the mouse):

  • Chrome does not fire the mouseenter event on page load
  • Firefox does fire the mouseenter event on page load

Below is an example snippet. To reproduce the issue, hover over the div and then refresh the page. In Chrome, the div does not contain "mouseenter". In Firefox, it does.

Note that this does not work in the Stacksnippets environment since you need to click "run snippet" first. JSFiddle: https://jsfiddle.net/9fu6cx5d/7/

 let div = document.getElementById('my-div'); div.addEventListener('mouseenter', function () { div.innerHTML = 'mouseenter'; });
 #my-div { width: 150px; height: 150px; background-color: #aaaaaa; }
 <div id="my-div"> </div>

Which browser has the correct behaviour? How can I work around the difference in behaviour or at least make them both behave the same?

Chrome version: 59.0.3071.115 (Official Build) (64-bit)

Firefox version: 54.0 (64-bit)

As pointed out in the comments, Chrome's behavior is the correct one according to the specs. Below is an idea on how to work around the difference.

You can make sure you get the value right by checking whether the mouse is inside the bounds of the div on document load. Unfortunately there is no way in JS to check the mouse position without firing events, so you will have to resort to some hack involving CSS hover rules and checking against them on $(document).ready .

To quote this hilarious answer :

Overlay your page with a div that covers the whole document. Inside that, create (say) 2,000 x 2,000 elements (so that the :hover pseudo-class will work in IE 6, see), each 1 pixel in size. Create a CSS :hover rule for those elements that changes a property (let's say font-family). In your load handler, cycle through each of the 4 million elements, checking currentStyle / getComputedStyle() until you find the one with the hover font. Extrapolate back from this element to get the co-ordinates within the document.

NB DON'T DO THIS.

While you definitely shouldn't do this, the general idea of using non-effective hover styles for the sake of checking if an element is hovered without needing JS events is a good one if you just need to work around browser quirks. I'm using font-weight in the example below, but you can change it to whatever works for you.

The css

#my-div:hover {font-weight:700;}

The js

// Pseudocode!

var mouseIsInside = false,
    div = $('#my-div');

$(document).ready(function(){
    if (div.css('font-weight') === 700) {
        mouseIsInside = true;
    }

    doStuffIfMouseInside();
});

div.on('mouseenter', function(){
    mouseIsInside = true;
    doStuffIfMouseInside();
})

function doStuffIfMouseInside() {
    if (mouseIsInside) {
        ...
    }
}

If you add (function(){})(); around your code it seems to work in both browsers.

It seems that firefox might be firing events before the dom is available causing problems with mousein/out events.

See: https://jsfiddle.net/9fu6cx5d/8/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM