今天主要是将事件的阶段详细讲一下,还有一些是属于事件对象的常用属性和方法。
1. 注册事件和移除事件
注册事件:
addEventListener()
attachEvent()
移除事件:
removeEventListener()
detachEvent()
注意:
需要将元素的事件移除时,需要注意移除事件的执行函数要与注册事件时的执行函数为同一个,如果注册时事件执行函数为一个匿名函数时,就算移除事件时的匿名函数内容一致也无法将事件移除,因为匿名函数每一个都是定义的新的函数,不是唯一。所有注册时的事件执行函数需要进行函数申明后再进行调用函数。
兼容性问题:
移除事件与注册事件对应,也存在兼容性问题。处理兼容这种兼容方式叫能力检测:
注册事件兼容性:
function addEventListener(element, type, listener) {
//能力检测
if(element.addEventListener) {
element.addEventListener(type, listener, false);
}else if(element.attachEvent) {
element.attachEvent("on" + type, listener);
}else{
element["on" + type] = listener;
}
}
移除事件兼容性:
function removeEventListener(element, type, listener) {
//能力检测
if(element.removeEventListener) {
element.removeEventListener(type, listener, false);
}else if(element.detachEvent) {
element.detachEvent("on" + type, listener);
}else{
element["on" + type] = null;
}
}
2. 事件的三个阶段
2.1 捕获阶段:从document开始依次查询触发事件的最底层元素。
2.2 目标阶段:触发事件的元素执行事件处理函数。
2.3 冒泡阶段:依次将触发条件向上传递并执行父元素的同一类型的事件处理函数。
3. 事件冒泡
定义:
元素触发事件并执行完该事件处理函数时会将这个触发条件传递给父级元素,如果父级元素也注册了同样的事件则会被触发执行父元素该事件的处理函数并再传递给父级元素的父级元素,直至document为止。这种情形就行水中气泡一样,从气泡出现开始一直往上冒,直至冒出水面。
优点:
如果子元素们需要注册同样的事件和事件处理程序时可以之间给父元素注册事件,通过事件对象来获取触发事件的目标,且如果子元素需要动态创建时,新创建出来的元素也同时注册了事件,而通过传统遍历子元素依次注册事件的方法无法给动态创建出来的子元素注册事件。 -- 事件委托
缺点:
当父元素注册同一类的事件,但是执行的函数与子元素的执行函数有冲突时会直接影响到子元素的事件执行。可以用事件对象e.stopPropagation()的方法来阻止事件冒泡。
4. 事件对象e的常见属性
上次说过当事件触发时系统会返回一个与事件有关的事件参数e,又可以叫做事件对象,作为对象拥有一些常见的属性需要我们熟悉和学习。(一下就用e来代替事件对象)
4.1 e.target:始终最初触发事件的元素 IE8以前不支持target对应的属性是event.srcElement(ie8以前不支持e,只支持window.event)。
4.2 e.currentTarget:如果没有事件冒泡的情况时和e.target一样,当存在事件冒泡时e.currentTarget就指代当时执行事件处理函数的元素。
4.3 this:始终与e.currentTarget一样的
4.4 阻止事件冒泡
e.stopPropagation()
IE老版本 event.cancelBubble=true
4.5 阻止默认事件的执行
e.preventDefault()
IE老版本 event.returnValue = false
4.6 鼠标事件的参数
type:返回值为事件类型
eventPhase:事件阶段,返回值为一个数字,1代表事件捕获;2代表目标阶段;3代表事件冒泡。
shiftKey/ctrlKey/altKey:按下鼠标同时按下组合键
button:获取鼠标的按键返回一个鼠标键对应的数字