<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
li {
background-color: #00A000;
color: #fff;
list-style: none;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<ul id="ul">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
<li>555</li>
</ul>
</body>
<script>
// 事件委托和事件代理:
// 首先需要弄清一个概念:事件委托或事件代理:根据《js高级程序设计》一书(前端红宝书)来说就是利用事件冒泡,
// 只指定一个事件处理程序,就可以管理某一类型的所有时间。举一个栗子:
// dom需要事件处理程序,我们都会直接给它设置事件处理程序。but,如果有在ul中全部100个li需要添加事件处理程序,
// 其具有相同的点击事件,那么可以根据for来进行遍历,也可以根据上层的ul来进行添加。
// 在性能的角度来看,把ul建立事件会减少dom的交互次数,提高性能。
// 事件委托(代理)的原理:
// 事件委托是利用事件的冒泡原理来实现的,就是事件从最深的节点开始,
// 然后逐步向上传播事件。引用凌云之翼中的栗子:页面上有这么一个节点树,div>ul>li>a;
// 比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,
// 执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,
// 那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,
// 这就是事件委托,委托它们父级代为执行事件。
<!-- 給每一個子元素綁定 性能差 -->
// var aLi=document.getElementsByTagName('li')
// for(var i=0;i<aLi.length;i++){
// aLi[i].addEventListener('click', e => alert(e.target.innerText))
// }
<!-- 给父级绑定处理事件,利用冒泡原理来实现回调,性能好 -->
var oUl=document.getElementById('ul');
oUl.addEventListener('click', e => alert(e.target.innerText))
// 但是可能提问就来了,我只想当点击到li时能够弹出内容,如果ul中存在其他的元素被点击时不想被弹出内容,怎么办?
// 有一个绝招就是event对象提供的一个属性叫做target,返回事件的目标节点,我们成为事件源,
// 也就是说,target就可以标识位当前操作的dom,但不是当前的事件操作的dom。
// 这个是有兼容的,标准浏览器使用ev.target。IE浏览器就要使用event.srcElement。
// var oUl=document.getElementById('ul');
// oUl.addEventListener('click', e => {
// var e=e||window.event;
// var target=e.target||e.srcElement;
// if(target.nodeName.toLocaleLowerCase()=='li'){
// alert(e.target.innerText)
// }
// })
</script>