《JavaScript高级程序设计》笔记(3)
事件
事件冒泡
IE的事件流叫做事件冒泡(event bubbling),即事件开始时由具体的元素(文档中嵌套层次深 的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。
事件捕获
事件处理程序(事件侦听器)
HTML事件处理程序
DOM0级事件处理程序
var btn = document.getElementById("myBtn");
btn.onclick = function(){
alert("Clicked");
};
DOM2级事件处理程序
“DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener() 和** removeEventListener()**。所有 DOM节点中都包含这两个方法,并且它们都接受 3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。后这个布尔值参数如果是 true,表示在捕获 阶段调用事件处理程序;如果是 false,表示在冒泡阶段调用事件处理程序。
var btn = document.getElementById("myBtn");
btn.addEventListener("click", function(){
alert(this.id);
}, false);
IE事件处理程序
IE实现了与 DOM中类似的两个方法:attachEvent()和 detachEvent()。这两个方法接受相同 的两个参数:事件处理程序名称与事件处理程序函数。由于 IE8 及更早版本只支持事件冒泡,所以通过 attachEvent()添加的事件处理程序都会被添加到冒泡阶段。
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function(){
alert("Clicked");
});
**,attachEvent()的第一个参数是"onclick",而非 DOM的 addEventListener()方法中 的"click"。 **
在 IE 中使用 attachEvent()与使用 DOM0 级方法的主要区别在于事件处理程序的作用域。在使 用 DOM0级方法的情况下,事件处理程序会在其所属元素的作用域内运行;在使用 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;
}
}
};
//使用
var btn = document.getElementById("myBtn");
var handler = function(){
alert("Clicked");
};
EventUtil.addHandler(btn, "click", handler);
//这里省略了其他代码
EventUtil.removeHandler(btn, "click", handler);
事件对象 DOM中的事件对象
event
属性/方法 | 类型 | 读/写 | 说明 |
---|---|---|---|
bubbles | Boolean | 只读 | 表明事件是否冒泡 |
cancelable | Boolean | 只读 | 表明是否可以取消事件的默认行为 |
currentTarget | Element | 只读 | 其事件处理程序当前正在处理事件的那个元素 |
defaultPrevented | Boolean | 只读 | 为 true 表示已经调用了preventDefault() (DOM3级事件中新增) |
detail | Integer | 只读 | 与事件相关的细节信息 |
eventPhase | Integer | 只读 | 调用事件处理程序的阶段:1表示捕获阶段,2表 示“处于目标”,3表示冒泡阶段 |
preventDefault() | Function | 只读 | 取消事件的默认行为。如果cancelable是 true,则可以使用这个方法 |
stopImmediatePropagation() | Function | 只读 | 取消事件的进一步捕获或冒泡,同时阻止任何 事件处理程序被调用(DOM3级事件中新增) |
stopPropagation() | Function | 只读 | 取消事件的进一步捕获或冒泡。如果bubbles 为true,则可以使用这个方法 |
target | Element | 只读 | 事件的目标 |
trusted | Boolean | 只读 | 为true表示事件是浏览器生成的。为false表示事件是由开发人员通过JavaScript创建的 (DOM3级事件中新增) |
type | String | 只读 | 被触发的事件的类型 |
view | AbstractView | 只读 | 与事件关联的抽象视图。等同于发生事件的 window对象 |
var EventUtil = {
addHandler: function(element, type, handler){
//省略的代码
},
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 = https://www.it610.com/article/false;
}
},
removeHandler: function(element, type, handler){
//省略的代码
},
stopPropagation: function(event){
if (event.stopPropagation){
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
//使用
btn.onclick = function(event){
event = EventUtil.getEvent(event);
}
事件委托
//html结构
- Go somewhere
- Do something
- Say hi
//传统添加事件
var item1 = document.getElementById("goSomewhere");
var item2 = document.getElementById("doSomething");
var item3 = document.getElementById("sayHi");
EventUtil.addHandler(item1, "click", function(event){
location.href = "http://www.wrox.com";
});
EventUtil.addHandler(item2, "click", function(event){
document.title = "I changed the document's title";
});
EventUtil.addHandler(item3, "click", function(event){
alert("hi");
});
//事件委托
var list = document.getElementById("myLinks");
EventUtil.addHandler(list, "click", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(target.id){
case "doSomething":
document.title = "I changed the document's title";
break;
case "goSomewhere":
location.href = "http://www.wrox.com";
break;
case "sayHi":
alert("hi");
break;
} });
【《JavaScript高级程序设计》笔记(3)】在这段代码里,我们使用事件委托只为
元素添加了一个 onclick 事件处理程序。由于所有列表项都是这个元素的子节点,而且它们的事件会冒泡,所以单击事件终会被这个函数处理。我们知道, 事件目标是被单击的列表项,故而可以通过检测 id 属性来决定采取适当的操作。与前面未使用事件委托的代码比一比,会发现这段代码的事前消耗更低,因为只取得了一个 DOM元素,只添加了一个事件处理程序。虽然对用户来说终的结果相同,但这种技术需要占用的内存更少。所有用到按钮的事件(多数鼠标事件和键盘事件)都适合采用事件委托技术。推荐阅读
- 《月亮和六便士》(这个世界需要那些仰望星空的人)
- 读书记(澳大利亚小说《荆棘鸟》散记五)
- 《世说新语》里出现的那些逗比和脑残
- 小说|小说 | 谜踪记
- 绘本讲师训练营【6期】10/21阅读原创《阿莫的生病日》
- 2016-10-31《让未来现在就来》-彭小六
- 《醫.道》第246章
- 腾讯云原生数据库TDSQL-C入选信通院《云原生产品目录》
- 《金蔷薇》教我如何写不干的干货
- 《质量效应|《质量效应 仙女座》如何成为绝佳编剧的反面教材(下)(场景创作)