问题描述
|
在没有jQuery的情况下,在Javascript中实现类似mouseenter / mouseleave事件的最佳方法是什么?跨浏览器使用的最佳策略是什么?我正在考虑对mouSEOver / mouSEOut事件处理程序中的event.relatedTarget / event.toElement属性进行某种检查?
喜欢听听您的想法。
解决方法
(彻底改变了我糟糕的答案。让我们再试一次。)
假设您具有以下基本的跨浏览器事件方法:
var addEvent = window.addEventListener ? function (elem,type,method) {
elem.addEventListener(type,method,false);
} : function (elem,method) {
elem.attachEvent(\'on\' + type,method);
};
var removeEvent = window.removeEventListener ? function (elem,method) {
elem.removeEventListener(type,method) {
elem.detachEvent(\'on\' + type,method);
};
(非常简单,我知道。)
每当您实现mouseenter / mouseleave时,您只需将事件附加到
正常的mouseover / mouseout事件,然后检查两个重要的细节:
该事件的目标是正确的元素(或正确的元素的子元素)
事件的relatedTarget不是目标的子级
因此,我们还需要一个函数来检查一个元素是否为
另一个:
function contains(container,maybe) {
return container.contains ? container.contains(maybe) :
!!(container.compareDocumentPosition(maybe) & 16);
}
最后一个“陷阱”是我们如何删除事件侦听器。最快的方法
通过返回我们要添加的新函数来实现它。
因此,我们最终得到这样的结果:
function mouseEnterLeave(elem,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,method2);
return method2;
}
添加mouseenter事件如下所示:
var div = document.getElementById(\'someID\'),listener = function () {
alert(\'do whatever\');
};
mouseEnterLeave(div,\'mouseenter\',listener);
为了删除该事件,您必须执行以下操作:
var newListener = mouseEnterLeave(div,listener);
// removing...
removeEvent(div,\'mouseover\',newListener);
这不是很理想,但是剩下的只是实现细节。的
重要的部分是if子句:mouseenter / mouseleave只是
鼠标悬停/鼠标悬停,但请检查您是否定位了正确的元素,以及
相关目标是目标的子级。
,恕我直言,最好的方法是制作自己的事件系统。
院长爱德华兹(Dean Edwards)几年前曾写道,我从过去汲取了一些线索。但是,他的解决方案确实可以立即使用。
http://dean.edwards.name/weblog/2005/10/add-event/
,约翰·雷西格(John Resig)将他的参赛作品提交给了比赛,在比赛中他被认为是最好的(注:迪恩·爱德华兹是陪审团之一)。因此,我想说一下,也检查一下。
偶尔使用jQuery和DOJO源代码,以查看他们使用的最佳实践以使其跨浏览器工作,也没有什么坏处。
,另一种选择是使用命中测试将真正的“ 5”事件与假(儿童生成的)事件区分开。像这样:
elt[\'onmouseout\']=function(evt){
if (!mouse_inside_bounding_box(evt,elt)) console.debug(\'synthetic mouseleave\');
}
我在chrome上使用了类似的方法,而警告者似乎可以解决问题。一旦有了可靠的mouseleave事件,mouseenter就变得微不足道了。