我一直在使用基本的javascript下拉菜单,使用addEventListener和attachEvent来处理单击和鼠标功能。 click事件subOpen调用的函数使用javascript“this”关键字来获取被点击元素的id。
添加活动的示例:
//add event listeners to menuitems
for (var i=0; i < menuitems.length; i++) {
if (menuitems[i].addEventListener) {
menuitems[i].addEventListener('click', subOpen, false);
menuitems[i].addEventListener('mouseout', closeTimer, false);
menuitems[i].addEventListener('mouseover', cancelTimer, false);
menuitems[i].addEventListener('selectstart', menucursorselect, false);
} else if (menuitems[i].attachEvent) {
menuitems[i].attachEvent('onclick', subOpen);
menuitems[i].attachEvent('onmouseout', closeTimer);
menuitems[i].attachEvent('onmouseover', cancelTimer);
menuitems[i].attachEvent('onselectstart', menucursorselect);
}
}
使用“this”关键字的subOpen函数示例:
function subOpen() {
cancelTimer(); //stops the close timer
if (submenudisplay) {
document.getElementById(submenudisplay).style.display = "none";
activeSubMenu = false;
}
var curMenuId = this.id;
var curSubMenuId = this.id + "submenu";
if (curSubMenuId) {
document.getElementById(curSubMenuId).style.display = "block";
activeSubMenu = true;
}
submenudisplay = curSubMenuId;
现在,除了早期版本的Internet Explorer之外,一切都在我测试的所有浏览器中都有效。对于旧版本的IE,调试器将“this.id”标记为未定义,因此它不知道要打开哪个子菜单。我做了一些研究,发现旧IE在附加事件时没有复制该函数,但引用它,所以我无法用“this”关键字捕获任何有用的数据。
我想知道是否有一个不同的关键字或函数可以用来完成与旧版IE一样的事情。
我的测试代码的完整版本可以找到here:
答案 0 :(得分:4)
您可以使用调用处理程序的函数并手动设置this
值。
这里我创建了一个接收元素和处理程序的bindHandler
函数,并返回一个新的处理程序,该处理程序调用原始处理程序,并将该元素作为this
值。
它还将window.event
对象传递给原始处理程序以获得一致性。
for (var i=0; i < menuitems.length; i++) {
if (menuitems[i].addEventListener) {
menuitems[i].addEventListener('click', subOpen, false);
menuitems[i].addEventListener('mouseout', closeTimer, false);
menuitems[i].addEventListener('mouseover', cancelTimer, false);
menuitems[i].addEventListener('selectstart', menucursorselect, false);
} else if (menuitems[i].attachEvent) {
menuitems[i].attachEvent('onclick', bindHandler(menuitems[i], subOpen));
menuitems[i].attachEvent('onmouseout', bindHandler(menuitems[i], closeTimer));
menuitems[i].attachEvent('onmouseover', bindHandler(menuitems[i], cancelTimer));
menuitems[i].attachEvent('onselectstart', bindHandler(menuitems[i], menucursorselect));
}
}
function bindHandler(elem, handler) {
return function() {
return handler.call(elem, window.event);
};
}
FWIW,我将创建一个单独的绑定函数,为您减少一些重复的代码。
for (var i=0; i < menuitems.length; i++) {
bindHandler(menuitems[i], 'click', subOpen);
bindHandler(menuitems[i], 'mouseout', closeTimer);
bindHandler(menuitems[i], 'mouseover', cancelTimer);
bindHandler(menuitems[i], 'selectstart', menucursorselect);
}
function bindHandler(elem, type, handler) {
if (elem.addEventListener)
elem.addEventListener(type, handler, false);
else if (elem.attachEvent)
elem.attachEvent("on" + type, function() {
return handler.call(elem, window.event);
};
}
答案 1 :(得分:1)
function addHandler(elem, type, handler) {
elem.addEventListener(type, handler, false);
}
if (!document.addEventListener)
addHandler = function(elem, type, handler) {
elem.attachEvent('on'+type, function() {
handler.call(elem, window.event);
});
};
然后使用
for (var i=0; i<menuitems.length; i++) {
addHandler(menuitems[i], 'click', subOpen);
addHandler(menuitems[i], 'mouseout', closeTimer);
addHandler(menuitems[i], 'mouseover', cancelTimer);
addHandler(menuitems[i], 'selectstart', menucursorselect);
}
答案 2 :(得分:1)
您应该使用jQuery绑定事件,而不是直接调用addEventListener
和attachEvents
函数。 jQuery将解决这些跨浏览器兼容性问题。
所以我的答案不是这样做的。但是如果你这样做,请知道Internet Explorer调用的函数默认没有this
关键字。要访问元素,您必须在window.event.srcElement
中查找元素。在兼容W3C的浏览器上,您可以使用this
或event.target
。您可以使用_addEventListener
下面的函数作为W3C函数的跨浏览器版本。
var _addEventListener = function (obj, evt, ofnc, bubble) {
var fnc = function (event) {
if (!event || !event.target) {
event = window.event;
event.target = event.srcElement;
}
return ofnc.call(obj, event);
};
// W3C model
if (obj.addEventListener) {
obj.addEventListener(evt, ofnc, !!bubble);
return true;
}
// M$ft model
else {
return obj.attachEvent('on' + evt, fnc);
}
};
//add event listeners to menuitems
for (var i = 0; i < menuitems.length; i++) {
_addEventListener(menuitems[i], 'click', subOpen, false);
_addEventListener(menuitems[i], 'mouseout', closeTimer, false);
_addEventListener(menuitems[i], 'mouseover', cancelTimer, false);
_addEventListener(menuitems[i], 'selectstart', menucursorselect, false);
}
答案 3 :(得分:-1)
实际的“事件”被传递给处理函数,您可以从事件中获取元素。