javascript与html的交互是通过事件来实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用侦听器(或处理程序)来预定事件,以便事件发生时执行相应的代码。
响应某个事件的函数就是事件处理程序(事件侦听器)。
事件流描述的是从页面中接收事件的顺序。
事件冒泡、捕获与委托
1、事件冒泡
IE的事件流叫做事件冒泡(event bubbling)。这个事件从原始元素开始一直冒泡到DOM树的最上层。
阻止事件冒泡的方式:
(1)用js阻止冒泡(存在兼容问题):
支持谷歌、火狐、IE11:event.stopPropagation() 这种方法是W3C支持的方法
支持IE10以下的:event.cancelBubble = true;
(2)用jQuery 阻止冒泡事件
方法一:event.stopPropagation();
方法二:return false;
2、事件捕获
事件捕获是从上级元素到下级元素。IE6只有冒泡,没有捕获。
事件注册方式中的 addEventListener() 存在一个boolean类型的参数
addEventListener(type,fn,boolean) type: 事件的类型 fn: 监听到事件后处理事件的函数
boolean:(false/true):当boolean为false的时候,为事件冒泡,当boolean为true时,为事件捕获,不写默认事件冒泡。
3、事件委托
对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件逐层冒泡并能被父级元素捕获,使用代理机制,只需给外层元素绑定一个处理器,就可以在其子元素上促发的所有事件。
4、事件处理程序
4.1 HTML事件处理程序
例:
封装在一个try-catch块中,以便错误不会浮出水面
缺点:
(1)这样扩展事件处理程序的作用域链在不同浏览器中会导致不同的结果;
(2)HTML与javascript代码紧密耦合。
4.2 DOM0级事件处理程序
例:
var btn = document.getElementById('myBtn');
btn.onclick = function() {
alert(this.id);
}
使用DOM0级方法指定的事件处理程序被认为是元素的方法。这时事件处理程序在元素的作用于中运行。程序中的this引用当前元素。
btn.onclick = null; // 删除事件处理程序
4.3 DOM2级事件处理程序
addEventListener()
removeEventListener()
特点:可以添加多个事件处理程序,事件处理程序按顺序触发。
移除时传入的参数与添加处理程序时使用的参数相同。通过addEventListener()添加的匿名函数将无法移除。
var btn = document.getElementById('myBtn');
var handler = function() {
alert(this.id);
};
btn.addEventListener('click',handler,false);
btn.removeEventListener('click',handler,false); //有效
4.4 IE事件处理程序(IE和opera)
attachEvent(事件处理程序名称, 事件处理程序函数)
detachEvent()
在IE中使用atachEvent()与使用DOM0级方法的主要区别:事件处理程序的作用域。
(1)DOM0级方法:事件处理程序会在其所属元素的作用域内运行;
(2)attachEvent()方法:在全局作用域中运行,this等于window
var btn = document.getElementById('myBtn');
btn.attchEvent('onclick',function() {
alert(this === window); // true
});
特点:可以添加多个事件处理程序,事件处理程序以相反的顺序被触发。
var btn = document.getElementById('myBtn');
var handler = function() {
alert('clicked');
};
btn.attachEvent('onclick',handler);
btn.detachEvent('onclick',handler);
4.5 跨浏览器的事件处理程序
var EventUtil = {
addHandler: function(element, type, handler) {
if(element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attchEvent) {
element.attchEvent("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);
5、事件对象
跨浏览器的事件对象
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 = false;
}
},
removeHandler: function(element, type, handler) {
// 代码省略
},
stopPropagation: function(event) {
if(event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
var link = document.getElementById("myLink");
link.onclick = function(event) {
event = EventUtil.getEvent(event);
EventUtil.preventDefault(event);
}