在学习
事件代理
之前,我们首先要知道一个概念:
事件冒泡
事件冒泡
事件捕获:
当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。
事件目标:
当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。
事件冒泡:
从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。
这是当一个事件触发时的三个阶段。
我们看一个例子:
<div onclick="d()">
<ul id="myul">
<li>1</li>
<li>2</li>
<li onclick="fun()">3</li>
</ul>
</div>
<!-- DOM树:html->body->div->ul->li -->
<script>
function d(){
console.log("我是div");
}
function fun(){
console.log("我是li");
}
</script>
当我们点击
li
时,首先从上到下进行事件捕获,然后执行函数,再事件冒泡,从当前元素逐级向上,如果有相同的事件就会触发。
更好的理解为,html在页面中包含body、div、ul、li这些元素,body在页面中包含div、ul、li,div包含ul 、li ,li其实是位于ul的空间上,也位于div的空间上,如果li被点击,也就相当于ul div body html被点击,因为li就是在他们的空间上啊,所以有绑定事件的就会触发。
事件代理
事件代理
又叫事件委托,就是利用
事件冒泡的原理
,把本应该注册在子元素上的事件,注册在父元素上。点击子元素时,没有相应的注册事件,就会到父元素上寻找。
我相信大家学习这个的时候都见过这个例子:
有三个同事预计会在周一收到快递。为签收快递,有两种办法:一是三个人在公司门口等快递;二是委托给前台MM代为签收。现实当中,我们大都采用委托的方案(公司也不会容忍那么多员工站在门口就为了等快递)。前台MM收到快递后,她会判断收件人是谁,然后按照收件人的要求签收,甚至代为付款。这种方案还有一个优势,那就是即使公司里来了新员工(不管多少),前台MM也会在收到寄给新员工的快递后核实并代为签收。
事件代理的
好处
就是:
- 当添加的事件太多的时候,需要不断的与
节点进行交互,会延长整个页面的交互就绪时间。事件代理减少了dom
操作,提高性能。dom
- 新添加的子元素也会有相应的事件。
例子:
<body>
<div>
<table>
<tr>
<th>学号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>操作</th>
</tr>
<tr>
<td>201211036</td>
<td>小红</td>
<td>女</td>
<td>19</td>
<td><input type="button" value="删除"></td>
</tr>
<tr>
<td>201211089</td>
<td>小屁</td>
<td>男</td>
<td>18</td>
<td><input type="button" value="删除"></td>
</tr>
<tr>
<td>201211143</td>
<td>小绿</td>
<td>女</td>
<td>17</td>
<td><input type="button" value="删除"></td>
</tr>
</table>
</div>
</body>
我们做一个这样的表格,实现各行的删除操作。如果按之前的事件来写,应该为每一行都添加一个事件。
<script>
var tab=document.querySelector("table");//这个方法是返回文档中匹配css选择器的第一个元素
tab.onclick=function(event){
var tar=event.target;//event就是事件对象,包含了发生事件的各种信息,target保存了发生事件的节点
//这种写法是为了浏览器的兼容
if((tar)&&tar.nodeName.toLowerCase()==='input'){//点击删除按钮
tar.parentNode.parentNode.parentNode.removeChild(tar.parentNode.parentNode);
}
}
var row=tab.insertRow(tab.rows.length);
var num=row.insertCell(0);
num.innerHTML="201512036";
var na=row.insertCell(1);
na.innerHTML="小黄";
var sex=row.insertCell(2);
sex.innerHTML="男";
var age=row.insertCell(3);
age.innerHTML="20";
var btn=row.insertCell(4);
btn.innerHTML="<input type='button' value='删除' />";
var ttr=document.createElement("tr");
ttr.innerHTML="<td>20365897<\/td><td>小明<\/td><td>男<\/td><td>15<\/td><td><input type='button' value='删除' \/><\/td>";
tab.appendChild(ttr);
//使用原生js添加的方法
</script>
可以看到后面添加的行也可以删除,也有了相应的事件。