javascriptmouseeventinnerhtmladdeventlistenermouseenter

Mouseenter event listener fires multiple times while moving mouse within element but only when updating the innerHTML


In my code I am attempting to update the innerHTML of a button on a mouseenter event.

I would expect the event to fire once each time my mouse moves into the element, but instead while my mouse is moving within the element, the event listener fires multiple times. If I remove the line updating the innerHTML within my event listener I get the expected behavior.

Why is this and how can I fix it? Please see the below code and linked JSFiddle.

https://jsfiddle.net/h7gsv69m/2/

var box = document.getElementById('box');
var button = document.createElement('button');
button.innerHTML = '<svg><use xlink:href="#icon-added"></use></svg>';

button.addEventListener('mouseenter', function() {
    document.getElementById('log').innerHTML += '<li>Mouseenter</li>';
    var iconHover = this.dataset.iconHover;
    //Comment out the following line to see expected behavior.
    this.innerHTML = '<svg><use xlink:href="#icon-remove"></use></svg>';
});

box.appendChild(button);

Solution

  • SVG's have a possible attribute called pointer-events. This attribute determines if the SVG may be the target of a mouse event. When the SVG becomes the target of the event, the original element is no longer the target, and when you leave the SVG, it causes the original element to become the target again, which causes another event to fire. You can solve this issue by just adding pointer-events: none; to your SVG class:

    button svg {
        width: 22px;
        height: 22px;
        pointer-events:none;
    }
    

    See updated Fiddle