直接上图:
1.事件冒泡
说明:inner盒子被嵌套再outer盒子内部,两个盒子都绑定点击事件的事件处理函数。
点击inner盒子的结果:inner的点击事件处理函数执行后,outer的点击事件处理函数也被执行了。
结论:点击inner时,outer的点击事件也会被触发。
讲解:事件冒泡是由一个元素的事件被触发而发生,该元素的这个事件会一级一级向父级传递并触发直到body,既然这些父级元素的这个事件都会被触发,那么这些父级元素的这个事件所绑定的事件处理函数就会被执行,这种事件向父级元素传递触发的现象叫事件冒泡。
2、事件对象与事件源对象
废话不多说,先上图
说明:我们在outer内部写了4个盒子,并给每个盒子绑定点击事件处理函数,根据事件冒泡现象来判断,虽然我们现在在物理的角度上无法点击到outer了,但是点击4个inner盒子,触发自己的点击事件的同时,这个点击事件依然会向outer盒子传递,并执行outer的点击事件处理函数。
我们想完成『点击哪个inner盒子,就打印出哪个盒子的编号』这个功能,非要给每个inner盒子绑定点击事件处理函数吗?答案:肯定不是的。
这里我们引出两个事件对象与事件源对象。
看下图:
事件对象:事件发生的那一刻,所有被记录的信息(鼠标的坐标系,点击到的哪个元素)等都会被记录到一个对象当中,这个对象就是事件对象。
获取事件对象的方式:
IE浏览器:window.event
其他浏览器:事件处理函数的第一个参数event
事件对象中保存着一个无比重要的东西:事件源对象
事件源是什么呢?它被保存在事件对象中,它保存着事件作用的元素(比如点击在具体哪个元素上),它也是一个对象,所以叫事件源对象。
这两个东西保存在事件对象中,访问的方式:
e.target || e.srcElement
IE浏览器:e.srcElement
其他浏览器:e.target
接下来我们来看看,如何通过outer的点击事件处理函数找到事件源对象
通过事件源对象来获取到事件具体作用在哪个元素上,那么我们就可以通过事件源来得到该元素的类名。
接下来我们通过判断className来分别执行不同的程序
总结一下:给父级盒子outer绑定事件处理函数,但是我的目标是点击4个inner盒子分别打印出相应的编号,本身应该给4个inner绑定事件处理函数的,由于事件冒泡,点击4个inner盒子,点击事件会冒泡到outer上并执行outer的点击事件处理函数,那么接下来我们可以通过事件对象与事件源对象获取到当前点击的元素的类名,通过对类名的判断打印相应的编号,这样由父级做事件的代理方,实际完成的是子元素事件任务的方式,我们叫做事件代理,或者事件委托。
事件代理的应用场景:
简单的说,所有列表项功能或者,盒子内部的元素有相同的事件需要触发执行不同的任务的情况下,都应该使用时间代理。
例子:列表项删除
需求:点击删除按钮,删除这一项。
非事件代理的做法:给每一个删除按钮都绑定一个事件处理函数来删除本项。
事件代理的做法:给ul绑定一个事件处理函数,通过事件源对象找到当前项的li,执行删除。