大家在工作中使用事件代理 对于事件代理今天来唠唠
事件代理的原理
事件代理简单来说: 就是把一个元素的响应事件函数代理都另一个元素上
事件代理的原理:利用事件冒泡在父元素来监听子元素触发的事件 。 dom遍历 一个父元素包含多个子元素 当一个事件被触发时候是否触发了某一种类型的元素呢?
扯事件冒泡 先来扯下事件 一步步来
事件流
事件流简单来说就是从页面上接收事件的一个顺序 这样就将事件这个流分成了事件捕获流和事件冒泡流
附上一个图
在ie的事件流叫事件冒泡 事件开始于目标元素 逐级向上传播到较为不具体的节点
事件捕获 事件开始较为不觉体的节点逐级向下都最后的目标元素
来上段经典的代码来扯扯
<ul id="ul">
<li id= "one">111</li>
<li id= "two">222</li>
</ul>
var one=document.getElementById("one");
var two=document.getElementById("two");
one.onclick = function () {
console.log('one')
}
two.onclick = function () {
console.log('two')
}复制代码
这种传统写法 如果是子元素很少 就一个两个 这种做法我觉得是能容忍 但是一般情况下都是有很多 要一个个添加事件处理程序 可能导致原因
- 因为函数都是对象 这样会占用内存 导致性能差
- 事先指定了所有事件处理程序 导致dom访问次数增加 肯定延迟整个页面交互就绪时间
可以看到这种传统干法就导致 要指定所有事件处理程序
事件代理
所有使用事件代理的方式 来看下案例
<ul id="ul">
<li>one</li>
<li>two</li>
</ul>
var ul =document.getElementById("ul");
ul.addEventListener('click', function () {
console.log("点击元素")
})复制代码
这里通过事件的冒泡将所点击元素代理到父元素ul上 这里看着是代理到了父元素上可以每次打印都是一样的 要证明到底点的那个子元素 在来看下上面代码的变化
<ul id="ul">
<li>one</li>
<li>two</li>
</ul>
var ul =document.getElementById("ul");
ul.addEventListener('click', function (e) {
var e = e || window.event;
var target = e.target || e.srcElement
if (target.nodeName.toLocaleLowerCase() =='li') {
console.log(target.innerHtml)
}
})复制代码
e是事件对象 点击子元素时候 代理到父元素上 利用事件冒泡 只要判断当前节点是不是li标签来触发当前li内容
利用事件代理和传统上处理有啥优点
- 事件代理 减少了事件注册 少了事件处理程序 节省了内存占用
- 简化dom节点更新时候 相应事件的更新
利用事件代理和传统上处理有啥缺点
- 因为所有的事件要基于事件冒泡 对于不冒泡的事件不支持
- 如果层嵌套的太深 冒泡过程中 可能会被某个层阻止
上面简单说了事件代理的很小的一点 还有很多知识需要去学习 知道了事件代理是在触发时候利用冒泡向上触发 然后子元素来享受父元素事件