原理
DOM2.0的事件模型是这样的
- 捕获阶段 :如果某个元素触发一个事件,如onclick,顶层对象document就会发出一个事件流,随着DOM树往目标元素流去,沿途的元素如果绑定了事件,它是不会执行的! (原Netscape的事件执行模式)
- 目标元素阶段: 到达了目标元素,执行它上面的绑定事件,但如果onclick只是个空实现,当然是没有效果啦!
- 起泡阶段: 从目标元素往顶层元素折回,如果沿途有onclick事件,就随个触发!(原IE的事件执行模式)
因此我们是点击了a元素,但它的onclick事件为空,当事件流上浮到ul元素时,发现ul元素绑定了onclick事件,就执行当中的函数。如果ul的祖先元素也绑定了onclick事件呢?!继续执行!有多少执行多少!看下面例子:
e.g.:
<!doctype html>
<html dir="ltr" lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<style type="text/css">
body {
background: #fff;
}
a {
color: #8080C0;
text-decoration: none;
border-bottom: 2px solid #fff;
}
a:hover {
color: #336699;
border-bottom-color: #B45B3E;
}
</style>
<script type="text/javascript">
var addEvent = (function () {
if (document.addEventListener) {
return function (el, type, fn) {
el.addEventListener(type, fn, false);
};
} else {
return function (el, type, fn) {
el.attachEvent('on' + type, function () {
return fn.call(el, window.event);
});
}
}
})();
window.onload = function () {
var nav = document.getElementById("nav");
nav.onclick = function () {
var e = arguments[0] || window.event,
target = e.srcElement ? e.srcElement : e.target;
console.log(target.nodeName);
if (target.nodeName == "A")
target.style.backgroundColor = "red";
e.stopPropagation();
return false;
}
var wrapper = document.getElementById("wrapper");
addEvent(wrapper, 'click', function () {
this.style.backgroundColor = "blue";
console.log("冒泡过程连我也惊动了!");
});
}
</script>
<title>delegate</title>
</head>
<body>
<div id="wrapper">
<ul id="nav">
<li><a href="http://www.cnblogs.com/">博客园</a></li>
<li><a href="http://www.blueidea.com/">蓝色理想</a></li>
<li><a href="http://www.51js.com/html/bbs.html">无忧脚本</a></li>
<li><a href="http://www.javaeye.com/">javaeye</a></li>
<li><a href="http://community.csdn.net/">CSDN</a></li>
</ul>
</div>
</body>
</html>
基本思路
- 获取所需元素的父元素
- 为父元素添加事件
- 获取 event 和 target
- 筛选 target 并为其添加事件
- 阻止事件冒泡
window.onload = function () {
var nav = document.getElementById("nav");
nav.onclick = function () {
var e = arguments[0] || window.event,
target = e.srcElement ? e.srcElement : e.target;
console.log(target.nodeName);
if (target.nodeName == "A")
target.style.backgroundColor = "red";
e.stopPropagation();
return false;
}
var wrapper = document.getElementById("wrapper");
addEvent(wrapper, 'click', function () {
this.style.backgroundColor = "blue";
console.log("冒泡过程连我也惊动了!");
});
}
参考自 javascript事件代理