没有JQuery的mouseenter

时间:2011-05-25 20:48:00

标签: javascript javascript-events

在没有jQuery的情况下,在Javascript中实现mouseenter / mouseleave like事件的最佳方法是什么?跨浏览器使用的最佳策略是什么?我正在考虑对mouseover / mouseout事件处理程序中的event.relatedTarget / event.toElement属性进行某种检查?

喜欢听你的想法。

4 个答案:

答案 0 :(得分:14)

(完全改变了我的可怕答案。让我们再试一次。)

假设您有以下基础跨浏览器事件方法:

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);
    };

(很简单,我知道。)

每当您实施mouseenter / mouseleave时,只需将事件附加到 正常的mouseover / mouseout事件,但然后检查两个重要的细节:

  1. 事件的目标是正确的元素(或正确元素的子元素)
  2. 事件的relatedTarget不是目标
  3. 的子项

    所以我们还需要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);
    }
    

    最后一个“问题”是我们如何删除事件监听器。最快捷的方式 实现它只是返回我们正在添加的新函数。

    所以我们最终得到这样的东西:

    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;
    }
    

    添加mouseenter事件将如下所示:

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

    要删除该事件,您必须执行以下操作:

    var newListener = mouseEnterLeave(div, 'mouseenter', listener);
    
    // removing...
    removeEvent(div, 'mouseover', newListener);
    

    这并不理想,但剩下的只是实施细节。该 重要的部分是if子句:mouseenter / mouseleave就是 mouseover / mouseout,但检查你是否针对正确的元素,以及是否 相关目标是目标的孩子。

答案 1 :(得分:2)

最好的方式,imho,就是制作自己的活动系统。

几年前,迪恩爱德华兹曾写过一篇关于我过去从中获取线索的文章。然而,他的解决方案开箱即用。

http://dean.edwards.name/weblog/2005/10/add-event/

答案 2 :(得分:1)

John Resig将他的entry提交给contest,其中他被评为最佳(注:Dean Edwards是其中一名陪审团成员)。所以,我想说,也检查一下。

通过jQuery,DOJO来源,偶尔也可以看到他们用来使其跨浏览器工作的最佳实践。

答案 3 :(得分:0)

另一种选择是使用命中测试来区分真实mouseout事件和假(子项生成)事件。像这样:

elt['onmouseout']=function(evt){
  if (!mouse_inside_bounding_box(evt,elt)) console.debug('synthetic mouseleave');
}

我在chrome上使用了这样的东西,而且需要注意的是,它似乎可以解决这个问题。一旦你有一个可靠的mouseleave事件,mouseenter就很简单了。