这一行:
var node = (e && e.target) || (window.event && window.event.srcElement);
相当于这个逻辑:
var node;
if (e && e.target) {
node = e.target;
} else if (window.event && window.event.srcElement) {
node = window.event.srcElement;
} else {
node = undefined;
}
这段代码的目的是处理旧版本的 IE 不将事件结构传递给事件处理程序的事实。相反,它存储在全局变量中window.event
,并且事件目标也存储在事件的差异属性中。
做这样的事情更常见(我认为更具可读性):
function showTab(e) {
// get the event data structure into e
e = e || window.event;
// get the source of the event
var node = e.target || e.srcElement;
alert(node.innerHTML);
}
实际上,任何体面的项目都应该使用库函数来抽象事件处理程序中的差异,这样特定于浏览器的代码只需要在项目中的一个位置,或者使用像 jQuery 这样的预构建库来处理这类事情。这是一个跨浏览器事件处理程序:
// refined add event cross browser
function addEvent(elem, event, fn) {
if (typeof elem === "string") {
elem = document.getElementById(elem);
}
function listenHandler(e) {
var ret = fn.apply(this, arguments);
if (ret === false) {
e.stopPropagation();
e.preventDefault();
}
return(ret);
}
function attachHandler() {
// older versions of IE
// set the this pointer same as addEventListener when fn is called
// make sure the event is passed to the fn also so that works the same too
// normalize the target of the event
window.event.target = window.event.srcElement;
var ret = fn.call(elem, window.event);
if (ret === false) {
window.event.returnValue = false;
window.event.cancelBubble = true;
}
return(ret);
}
if (elem.addEventListener) {
elem.addEventListener(event, listenHandler, false);
} else {
elem.attachEvent("on" + event, attachHandler);
}
}