事件模型
模型类型:DOM 0(原始事件类型)、DOM 2
DOM 0
- 直接在dom上绑定事件。列如:div.nclick =function(){};
特点: - 1、DOM0级事件模型是早期的事件模型,所有的浏览器都是支持的。
- 2、一个DOM对象只能注册一个同类型的函数,因为注册多个同类型的函数的话,就会发生覆盖,之前注册的函数就会无效。
- 3、DOM0不会阻止事件冒泡的发生
DOM 2
使用addEventListener和removeEventListener来注册和解除事件
支持事件流的捕获和冒泡,通过addEventListener(‘事件名称’,‘事件回调’,‘捕获/冒泡’)第三个参数的设置(默认false即冒泡),制定事件触发是在捕获过程还是冒泡过程。
addEventListener() 移除事件必须使用外部函数
在DOM 2中 一个dom对象可以注册多个相同类型的事件,不会发生事件的覆盖,会依次的执行各个事件函数。
"DOM 2"规定事件流的三个阶段:
- 第一阶段:捕获阶段,从全局对象传导到目标节点
- 第二阶段:目标阶段,事件在目标节点上触发
- 第三阶段:冒泡阶段,从目标节点传回window对象
事件捕获阶段、事件目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会;然后是实际的目标接收到事件;最后一个阶段是冒泡阶段,可以在这个阶段对事件作出响应,
即:事件捕获->事件处理->事件冒泡
事件委托
事件委托原理:事件委托是利用事件的冒泡原理来实现的,何为事件冒泡呢?
冒泡事件就是document到触发事件的那个节点一层层向下捕获直至事件源然后一层层向上冒泡。这就是事件冒泡,利用这个冒泡机制减少DOM操作,有一点要注意就是onclick不支持捕获事件,
举个例子:页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。
事件委托就是利用冒泡的原理,把本应该添加到某个元素上的事件委托给他的父级,从而减少DOM交互达到网页优化。
<ul id="ul">
<li><a href="#>aa</a></li>
<li><a href="#>bb</a></li>
<li><a href="#>nn</a></li>
</ul>
<script>
var ul = document.getElementById("ul");
ul.onclick = function(e){
var e = e || window.event;
var target = e.target || e.srcElement;
if(target.tagName == 'LI'){
console.log(target.innerHTML);
}
}
</scropt>
Event对象提供了一个属性叫target,可以返回事件的目标节点,也就是事件源节点,target就可以表示为当前的事件操作的dom,这个是有兼容性的,标准浏览器用ev.target,IE浏览器用event.srcElement,
此时只是获取了当前节点的位置,并不知道是什么节点名称,也可以用nodeName来获取具体是什么标签名
事件委托优点:
- 只在内存中开辟了一块空间,节省资源同时减少了dom操作,提高性能
- 对于新添加的元素也会有之前的事件
总结:什么样的事件可以用事件委托,什么样的事件不可以用呢?
适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。
不适合的就有很多了,举个例子,mousemove,mouseout,每次都要计算它的位置,非常不好把控,在不如说focus,blur之类的,本身就没用冒泡的特性,自然就不能用事件委托了。