事件委托
事件委托也称事件代理,由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation)。
事件冒泡/捕获
前面提到事件委托的实现是利用事件冒泡的机制,那么何为事件冒泡。
一个事件发生后,会在子元素和父元素之间传播。这种传播分成三个阶段。
捕获阶段:从window对象传导到目标节点(上层传到底层)
目标阶段:在目标节点上触发
冒泡阶段:从目标节点传导回window对象(从底层传回上层) ,事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定到外层。
事件委托的优点
- 减少内存消耗
如果我们有一个列表ul,列表之中有大量的列表项li,我们需要在点击列表项的时候响应一个事件。
<ul id="list">
<li>01</li>
<li>02</li>
<li>03</li>
<li>04</li>
<li>05</li>
</ul>
<script>
var ul = document.getElementById('list');
var lis = ul.getElementsByTagName('li');
for( var i=0;i<lis.length;i++ ){
lis[i].addEventListener('click',function(){
console.log(this.innerText);
},false);
}
</script>
在上面的代码中我们需要为每一个li都绑定上一个监听事件,这种重复性的操作我们就可以使用事件代理来实现。
ul.addEventListener('click',function(e){
console.log(e.target.innerText);
},false);
利用事件代理取代了之前为每一个li元素都绑定事件监听器的做法,无论从代码的简洁度还是性能上来说都是更加合理的,所以事件委托可以减少大量的内存消耗,节约效率。
事件种类
-
鼠标事件
click:按下鼠标(通常是按下主按钮)时触发。
dblclick:在同一个元素上双击鼠标时触发。
mousedown:按下鼠标键时触发。
mouseup:释放按下的鼠标键时触发。
mousemove:当鼠标在一个节点内部移动时触发。当鼠标持续移动时,该事件会连续触发。为了避免性能问题,建议对该事件的监听函数做一些限定,比如限定一段时间内只能运行一次。
mouseenter:鼠标进入一个节点时触发,进入子节点不会触发这个事件。
mouseover:鼠标进入一个节点时触发,进入子节点会再一次触发这个事件。
mouseout:鼠标离开一个节点时触发,离开父节点也会触发这个事件。
mouseleave:鼠标离开一个节点时触发,离开父节点不会触发这个事件。
contextmenu:按下鼠标右键时(上下文菜单出现前)触发,或者按下“上下文菜单键”时触发。
wheel:滚动鼠标的滚轮时触发。 -
键盘事件
keydown:按下键盘时触发。
keypress:按下有值的键时触发,即按下 Ctrl、Alt、Shift、Meta 这样无值的键,这个事件不会触发。对于有值的键,按下时先触发keydown事件,再触发这个事件。
keyup:松开键盘时触发该事件。 -
表单事件
change:当、、的值发生变化时触发。
input:当、、的值发生变化时触发。
select:当在、里面选中文本时触发。
invalid:用户提交表单时,如果表单元素的值不满足校验条件,就会触发invalid事件。
reset/submit:这两个事件发生在表单对象
上,而不是发生在表单的成员上。