Q:什么是事件
事件是文档或浏览器窗口中发生的一些特定的交互瞬间,是实现JavaScript与HTML交互的方式
Q:什么是事件流
事件流描述的是从页面中接收事件的顺序。IE的事件流是事件冒泡流,Netscape的事件流是事件捕获流
DOM2级事件规定的事件包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段,IE8及以下不支持事件捕获阶段
事件冒泡:事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)
事件捕获:和事件冒泡相反,先由文档接受,向下传播,直到最具体的元素
Q:IE与W3C事件处理程序及区别
DOM2级事件中添加和删除事件处理程序的方法:
方法接受的3个参数分别表示:事件名、事件处理函数、指定事件在捕获或冒泡阶段执行,false表示在冒泡阶段调用事件处理函数,true表示在捕获阶段调用事件处理函数,大多数情况在冒泡阶段执行以最大限度兼容各种浏览器。IE9和其它浏览器支持DOM2级事件处理程序。
var btn = document.getElementById("myBtn");
var handler = function() {
alert(this.id);
};
btn.addEventListener("click", handler, false);
btn.removeEventListener("click", handler, false);
IE事件:
var btn = document.getElementById("myBtn");
var handler = function() {
alert("Clicked");
};
btn.attachEvent("onclick", handler);
btn.detachEvent("onclick", handler);
DOM2 | IE |
接收3个参数 | 接收2个参数且第一个事件名有“on” |
false表示冒泡阶段执行,true表示捕获阶段执行 | 事件被添加到冒泡阶段 |
事件处理函数在其所属元素的作用域内运行 | 事件处理程序在全局作用域中运行 |
可添加多个事件处理程序,当为一个元素添加多个(点击)事件处理程序时,以添加的顺序执行 | 可添加多个事件处理程序,当为一个元素添加多个(点击)事件处理程序时,以相反的顺序执行 |
Q:DOM和IE中的事件对象
只有在事件处理程序执行期间,event对象才会存在;一旦事件处理程序执行完成,event对象就会被销毁
DOM事件对象 | IE事件对象 |
无论是使用DOM0或DOM2级方法指定事件处理程序,都会传入event对象到事件处理程序中 | DOM0级方法添加事件处理程序,event对象作为window对象的一个属性存在 var event = window.event; 使用attachEvent()添加,会有一个event对象作为参数传入事件处理程序,也可以通过window对象访问event对象 |
stopPropagation()取消事件的进一步捕获或冒泡(bubbles为true可以使用这个方法) | cancelBubble Boolean 默认值为false, true表示取消事件冒泡 |
preventDefault() 取消事件默认行为(cancelable是true可以使用这个方法) | returnValue Boolean 默认值为true,false表示取消事件默认行为 |
target 事件的目标 | srcElement 事件的目标 |
currentTarget 执行事件处理程序的那个元素 | - |
事件处理程序内的this始终等于currentTarget的值 | attachEvent()指定事件处理函数,其中的this指向window |
跨浏览器的事件处理程序及事件对象
var EventUtil = {
addHandler: function(element, type, handler) {
if(element.addEventListener) {
element.addEventListener(type, handler, false);
} else if(element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
removeHandler: function(element, type, handler) {
if(element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if(element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
},
getEvent: function(event) {
return event ? event : window.event;
},
getTarget: function(event) {
return event.target || event.srcElement;
}
stopPropagation: function(event) {
if(event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
},
preventDefault: function(event) {
if(event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
}
};
var btn = document.getElementById("btn");
var handler = function(event) {
event = EventUtil.getEvent(event);
let target = EventUtil.getTarget(event);
// return target;
}
EventUtil.addHandler(btn, "click", handler);
Q:什么是事件委托,有什么优势,手写一个例子
先写一个例子
<ul id="myUl">
<li id="a">a</li>
<li id="b">b</li>
<li id="c">c</li>
</ul>
var myUl = document.getElementById("myUl");
EventUtil.addHandler(myUl, "click", function(event){
event = EventUtil.getEvent(event);
let target = EventUtil.getTarget(event);
switch target.id {
case "a":
//do something
break;
case "b":
//do something
break;
case "c":
//do something
break;
}
});
事件委托是利用事件冒泡将事件处理程序添加到DOM树中尽量高的层次上,只指定一个事件处理程序,管理某一类型的所有事件,提升性能。
添加到页面的事件处理程序的数量直接关系到页面的整体运行性能,一是因为函数是对象,会占用内存,二是因为必须事先制定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间