Event
对象
Event
对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。一旦事件发生,便会生成Event
对象,如单击一个按钮,浏览器的内存中就产生相应的 event
对象。
- 事件通常与函数结合使用,函数不会在事件发生前被执行!
event
对象只在事件发生的过程中才有效。event
的某些属性只对特定的事件有意义。比如,fromElement
和toElement
属性只对onmouseover
和onmouseout
事件有意义。
firefox
里的event
跟IE里的不同,IE里的是全局变量,随时可用;firefox
里的要用参数引导才能用,是运行时的临时变量。
在IE/Opera
中是window.event
,在Firefox
中是event
;而事件的对象,在IE中是 window.event.srcElement
,在Firefox中是event.target
,Opera中两者都可用。
Event
对象属性和方法
clientX,clientY
:返回当事件被触发时,鼠标指针相对于浏览器窗口可视文档区域的左上角的的水平x坐标和垂直y坐标;screenX,screenY
:返回当某个事件被触发时,鼠标指针相对于显示器左上角的水平x坐标和垂直y坐标;offsetX,offsetY/layerX,layerY
:事件发生的时候,鼠标相对于源元素左上角的位置;x,y/pageX,pageY
:事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素;altKey,ctrlKey,metaKey,shiftKey
:返回当事件被触发时,”ALT”、”TRL”、”meta”、”SHIFT”
键是否被按下;keyCode
:返回keydown
和keyup
事件发生的时候按键的代码,以及keypress
事件的Unicode
字符(firefox2不支持event.keycode
,可以用event.which
替代 );button
:返回当onmousedown, onmouseup
, 和onmousemove
事件被触发时,哪个鼠标按钮被点击。对其他事件,不管鼠标状态如何,都返回0
(比如onclick
)。整数,1
代表左键,2
代表右键,4
代表中键,如果按下多个键,酒把这些值加起来,所以3就代表左右键同时按下(firefox中0
代表左键,1
代表中间键,2
代表右键);
可能的值:0 没按键 1 按左键 2 按右键 3 按左右键 4 按中间键 5 按左键和中间键 6 按右键和中间键 7 按所有的键
type
:事件的类型,如onlick
中的click
;srcElement/target
:事件源,就是发生事件的元素;relatedTarget
:返回与事件的目标节点相关的节点;fromElement,toElement
:对于mouseover
和mouseout
事件,fromElement
引用移出鼠标的元素,toElement
引用移入鼠标的元素;currentTarget
:返回其事件监听器触发该事件的元素;timeStamp
:返回事件生成的日期和时间;eventPhase
:返回事件传播的当前阶段,1表示捕获阶段,2表示处于目标,3表示冒泡阶段;detail
:表示的是与事件相关的细节信息bubbles
:返回布尔值,指示事件是否是起泡事件类型;cancelable
:返回布尔值,表示是否可以取消事件的默认行为;cancelBubble
:一个布尔属性,默认是false
。把它设置为true
的时候,将阻止事件进一步起泡到包容层次的元素;(e.cancelBubble= true;
相当于e.stopPropagation();
)returnValue
:一个布尔属性,设置为false
的时候可以阻止浏览器执行默认的事件动作;(e.returnValue =false;
相当于e.preventDefault();
)defaultPrevented
:表示是否调用了preventDefault()
initEvent(eventType,canBubble,cancelable)
:初始化新创建的Event
对象的属性;preventDefault()
: 通知浏览器不要执行与事件关联的默认动作;stopPropagation()
:不再派发事件;attachEvent(eventType, fn)
,detachEvent()/addEventListener(事件类型, 回调函数,事件机制),removeEventListener
:为制定DOM对象事件类型注册多个事件处理函数的方法,它们有两个参数,第一个是事件类型,第二个是事件处理函数。事件机制分为冒泡和捕获,如果为false
表示事件冒泡,为true
表示事件捕获。在attachEvent()
事件执行的时候,this
关键字指向的是window
对象,而不是发生事件的那个元素;
事件冒泡和事件捕获
事件流是描述从页面中接收事件的顺序**【从内到外(冒泡),从外到内(捕获)】**。
事件冒泡:事件可以沿着包容层次一点点起泡到上层,也就是说,下层的DOM节点定义的事件处理函数,到了上层的节点如果还有和下层相同事件类型的事件处理函数,那么上层的事件处理函数也会执行。例如, div
标签包含了 a
,如果这两个标签都有onclick
事件的处理函数,那么执行的情况就是先执行标签 a
的onclick
事件处理函数,再执行 div
的事件处理函数。如果希望的事件处理函数执行完毕之后,不希望执行上层的 div
的onclick
的事件处理函数了,那么就把cancelBubble
设置为true
即可。
事件捕获和事件冒泡刚好相反,它是事件从最不具体的节点(document
)先接收到事件,然后再向下逐一捕获至(文档中嵌套层次最深的那个点【当前绑定事件的那个元素】)。
简单地说,事件冒泡和事件捕获都是一种事件传递的机制。这种机制可以使事件在不同级的元素间传递。事件冒泡是从事件触发的源节点,向父节点传递,直到到达最顶节点。而事件捕获则是从最顶节点,逐步向下传递,直到到达事件触发的源节点。
DOM事件流如图(剪自javascript高级程序设计):
由图可知捕获过程要先于冒泡过程
Event
对象的一些兼容性写法
- 获得event对象兼容性写法
event || (event = window.event);
- 获得
target
兼容型写法
event.target||event.srcElement
- 阻止浏览器默认行为兼容性写法
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
- 阻止冒泡写法
event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);
event
事件的传递与冒泡处理示例
html:
<div>
<table nclick="gotClick(event,'table',this)" id="table">
<tr nclick="gotClick(event,'tr',this)" id="tr">
<td nclick="gotClick(event,'td',this)" id="td">
<input type="button" name="button" value="单击我"
onclick="gotClick(event,'按钮',this);" id="button">
</td>
</tr>
</table>
</div>
<div id='result'>
</div>
js:
function gotClick(event,msg,obj){
var msgs = msg+" => 被单击了!<br/>";
var object = event.target||event.srcElement;
document.getElementById('result').innerHTML +=msgs;
// event.cancelBubble=true;//阻止传递
}
运行结果是:
按钮 => 被单击了!
td => 被单击了!
tr => 被单击了!
table => 被单击了!
事件监听
addEventListener()
与removeEventListener()
用于处理指定和删除事件处理程序操作。
它们都接受3个参数:如addEventListener("事件名" , "事件处理函数" , "布尔值");
(注:事件名不含”on
”,如”click
”)
现在的版本可以省略第三个参数,默认值为false
,表示在冒泡阶段调用事件处理程序。如果为true
,则表示在捕获阶段调用事件处理程序。
示例:
要在body
上添加事件处理程序,可以使用下列代码:
document.body.addEventListener('touchmove', function (event) {
event.preventDefault();
},false);
通过addEventListener()
添加的事件处理程序只能使用removeEventListener()
来移除;移除时传入的参数与添加处理程序时使用的参数相同。这也意味着通过addEventListener()
添加的匿名函数无法移除。
错误用法示例:
document.body.addEventListener('touchmove', function (event) {
event.preventDefault();
},false);
document.body.removeEventListener('touchmove', function (event) {
event.preventDefault();
},false);
这个例子中,使用addEventListener()
添加一个事件处理程序。虽然调用removeEventListener()
是看似使用了相同的参数,但实际上,第二个参数与传入addEventListener()
中的那一个完全不同的函数。而传入removeEventListener()
中的事件处理程序函数必须与传addEventListener()
中的相同
正确用法示例:
function bodyScroll(event){
event.preventDefault();
}
document.body.addEventListener('touchmove',bodyScroll,false);
document.body.removeEventListener('touchmove',bodyScroll,false);
重写后的这个例子在addEventListener()
和removeEventListener()
中用的是相同的函数。
共用函数不能带参数,错误用法示例:
function bodyScroll(event){
event.preventDefault();
}
document.body.addEventListener('touchmove',bodyScroll(),false);
document.body.removeEventListener('touchmove',bodyScroll(),false);
总结:
1:相同事件绑定和解除,需要使用共用函数;绑定和解除事件时,事件没有”on”,即onclick
写成click
2:共用函数不能带参数;