function attachEvent(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
}
function addLoadHandler(handler) {
attachEvent(window, "load", handler);
}
function init() {
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
divs[i].onclick = function(event) {
alert(this.id); // 显示点击的div元素的id
};
}
addLoadHandler(function() {
console.log("Page loaded");
});
}
init();
在这个例子中,我们首先定义了一个名为 attachEvent
的函数,用于向DOM元素添加事件监听器。然后我们定义了一个名为 addLoadHandler
的函数,用于向窗口添加一个“load”事件处理器。
在 init
函数中,我们获取了所有 <div>
元素,并为每个元素添加了一个点击事件处理器。当用户点击一个 <div>
元素时,会弹出一个警告框显示该元素的ID。
此外,我们还使用 addLoadHandler
函数向窗口添加了一个 “load” 事件处理器,当页面加载完成后会在控制台打印一条消息。
虽然这段代码看起来没什么问题,但它实际上会导致内存泄漏。原因是每个 <div>
元素都有一个指向匿名函数的引用,而这个匿名函数又有一个指向包含它的 init
函数作用域的闭包。因此,只要这些 <div>
元素存在,它们的事件处理器就不能被垃圾回收机制清除,从而导致内存泄漏。
要解决这个问题,你可以使用命名函数而不是匿名函数作为事件处理器:
function handleDivClick(event) {
alert(this.id); // 显示点击的div元素的id
}
function init() {
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
divs[i].onclick = handleDivClick;
}
addLoadHandler(function() {
console.log("Page loaded");
});
}
init();
现在,所有的 <div>
元素都共享同一个函数实例,因此不会出现内存泄漏的问题。