Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mouseenter without JQuery

What would be the best way to implement a mouseenter/mouseleave like event in Javascript without jQuery? What's the best strategy for cross browser use? I'm thinking some kind of checking on the event.relatedTarget/event.toElement property in the mouseover/mouseout event handlers?

Like to hear your thoughts.

like image 760
Mansiemans Avatar asked May 25 '11 20:05

Mansiemans


People also ask

What is Mouseenter event in Javascript?

The mouseenter event is fired at an Element when a pointing device (usually a mouse) is initially moved so that its hotspot is within the element at which the event was fired.

What is Mouseenter event in jquery?

The mouseenter event occurs when the mouse pointer is over (enters) the selected element. The mouseenter() method triggers the mouseenter event, or attaches a function to run when a mouseenter event occurs..

What is the difference between Mouseout and Mouseleave?

This means that mouseleave is fired when the pointer has exited the element and all of its descendants, whereas mouseout is fired when the pointer leaves the element or leaves one of the element's descendants (even if the pointer is still within the element).


1 Answers

(Totally changed my terrible answer. Let's try again.)

Let's assume you have the following base, cross-browser event methods:

var addEvent = window.addEventListener ? function (elem, type, method) {
        elem.addEventListener(type, method, false);
    } : function (elem, type, method) {
        elem.attachEvent('on' + type, method);
    };

var removeEvent = window.removeEventListener ? function (elem, type, method) {
        elem.removeEventListener(type, method, false);
    } : function (elem, type, method) {
        elem.detachEvent('on' + type, method);
    };

(Pretty simple, I know.)

Whenever you implement mouseenter/mouseleave, you just attach events to the normal mouseover/mouseout events, but then check for two important particulars:

  1. The event's target is the right element (or a child of the right element)
  2. The event's relatedTarget is not a child of the target

So we also need a function that checks whether one element is a child of another:

function contains(container, maybe) {
    return container.contains ? container.contains(maybe) :
        !!(container.compareDocumentPosition(maybe) & 16);
}

The last "gotcha" is how we would remove the event listener. The quickest way to implement it is by just returning the new function that we're adding.

So we end up with something like this:

function mouseEnterLeave(elem, type, method) {
    var mouseEnter = type === 'mouseenter',
        ie = mouseEnter ? 'fromElement' : 'toElement',
        method2 = function (e) {
            e = e || window.event;
            var target = e.target || e.srcElement,
                related = e.relatedTarget || e[ie];
            if ((elem === target || contains(elem, target)) &&
                !contains(elem, related)) {
                    method();
            }
        };
    type = mouseEnter ? 'mouseover' : 'mouseout';
    addEvent(elem, type, method2);
    return method2;
}

Adding a mouseenter event would look like this:

var div = document.getElementById('someID'),
    listener = function () {
        alert('do whatever');
    };

mouseEnterLeave(div, 'mouseenter', listener);

In order to remove the event, you'd have to do something like this:

var newListener = mouseEnterLeave(div, 'mouseenter', listener);

// removing...
removeEvent(div, 'mouseover', newListener);

It's hardly ideal, but all that's left is just implementation details. The important part was the if clause: mouseenter/mouseleave is just mouseover/mouseout, but checking if you're targeting the right element, and if the related target is a child of the target.

like image 155
sdleihssirhc Avatar answered Sep 27 '22 00:09

sdleihssirhc