事件
一、事件流P346
1、在单击按钮的同时,你也单击了按钮的容器元素,甚至也单击了整个页面。“同心圆”例子
2、事件流描述的是页面中接受事件的顺序。
3、事件冒泡:事件开始时由最具体的元素(文档中嵌套才能够此最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)
4、事件捕获:不太具体的节点应该更早地接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于在事件到达预定目标之前捕获它。
5、DOM事件流:三个阶段:事件捕获阶段、出于目标阶段、事件冒泡阶段
二、事件处理程序 P348
1、HTML事件处理程序
1.1、独到之处
1、会创建一个封装着元素属性值的函数,这个函数中有事件对象event
2、扩展作用域
1.2、缺点
1、时差问题。因为用户可能会在HTML元素一出现在页面上就触发相应的事件,但当时的时间处理程序有可能尚不具备执行条件。
2、这样扩展时间处理程序的作用于连在不同浏览器中会导致不同结果。
3、HTML与JavaScript紧密耦合。
2、DOM 0级事件处理程序
2.1、存在的理由
1、简单
2、跨浏览器
2.2、每个元素(包括document和window)都有自己的事件处理程序属性。使用之前,必须取得需要操作对象的引用。
2.3、在代码运行以前不会指定事件处理程序,因此如果代码在页面中位于按键后面,就有可能在一段时间内怎么单击都没有反应。
2.4、程序中的this引用当前元素,在事件处理程序中通过this访问元素的任何属性和方法。
2.5、在事件流的冒泡阶段被处理。
2.6、删除:btn.onclick =null;
3、DOM 2级事件处理程序 P351
3.1、所有DOM节点都包含这两个方法。
3.2、通过addEventListener()添加的时间处理程序只能使用removeEventListener()来移除。移除时传入的参数与添加处理程序时使用的参数相同。这也意味着通过addEventListener()添加的匿名函数将无法移除。
3.3、大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度地兼容各种浏览器。最好只需要在事件到达目标之前截获它的时候将事件处理程序添加到捕获阶段。如果不是特别需要,不建议在事件捕获阶段注册事件处理程序。
4、IE事件处理程序 P352
4.1、事件处理程序会在全局作用域中运行,因此this等于window。
4.2、移除事件处理程序和DOM 2级一样。
5、跨浏览器
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.datachEvent){
element.detachEvent("on" + type, handler);
}else {
element["on" + type] = null;
}
}
//...........
}
三、事件对象 P355
在触发DOM上的某个事件时,会产生一个事件对象,这个对象中包含着所有与实践有关的信息。
1、DOM中的事件对象
1.1、DOM 0级与DOM 2级,都会传入event对象。
1.2、在通过HTML特性指定事件处理程序时,变量event中保存着event对象。
1.3、event对象包含与创建它的特定事件有关的属性和方法。触发的事件类型不一样,可用的属性和方法也不一样。
1.4、在事件处理程序内部,对象this始终等于currentTarget的值,而target则只包含事件的时机目标。如果直接将事件处理程序指定给了目标元素,则this、currentTarget和target包含相同的值。
1、事件代理:用事件对象的target属性,可以得到触发事件的元素。事件被激活后,会像猴子一样沿着DOM叔从监听节点下滑到触发节点,然后再上爬会监听节点。也就是说,如果你监听了一个DOM节点,也就等于其所有的后代节点。代理的意思就是只监听父节点的事件触发,以代理对其后代节点的监听,而你需要做的只是通过target属性得到触发元素并作出回应。
1.5、阻止特定时间的默认行为,可以使用preventDefault()方法。但是,只有cancelable属性设置为true的事件。
1.6、stopPropagation()方法用于立即停止时间在DOM层次中传播。
1.7、事件对象的eventPhase属性,可以用来确定事件当前正位于事件流的哪个阶段。
2、IE中的事件对象
2.1、DOM 0级方法时,event对象作为window对象的一个属性存在。
var btn = document.getElementById(“myBtn”);
btn.onclick = function(){
varevent = window.event;
alert(event.type);
};
2.2、attachEvent()
event对象作为参数被传入事件处理程序函数中。也可以像DOM 0级方法一样,window.event访问。
2.3、HTML特性指定的时间处理程序
通过名叫event的变量来访问event对象(与DOM事件中的时间模型相同)
2.4、IE的event对象同样也包含与创建它的时间相关的属性和方法。
2.5、IE中,event.returnValue属性相当于DOM中preventDefault()方法。
2.6、IE中,event.cancelBubble等于DOM中的stopPropagation()
3、跨浏览器
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.datachEvent){
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;
},
preventDefault:function(event){
if (event.preventDefault) {
event.preventDefault();
}else {
event.returnValue = false;
}
},
stopPropagation:function(event){
if (event.stopPropagation) {
event.stopPropagation();
}else {
event.cancelBubblt = true;
}
}
};
四、事件类型 P362
1、UI
2、焦点时间
3、鼠标事件
4、滚轮事件
5、文本事件
6、键盘事件
7、合成事件
8、变动事件
9、变动名称事件