事件对象Event
事件流
事件流指的是事件的发生顺序,包括三种:
- 事件的捕获阶段
事件的捕获是从上而下的,越高级的父级越早触发事件 - 处于的目标阶段
- 事件的冒泡阶段
让DOM树最底层的目标元素最先接收到事件,然后向上传递,是一个自下而上的过程
不支持冒泡的事件:
blur:元素失去焦点时触发,不支持冒泡。
focus: 元素获得焦点时触发,不支持冒泡。
mouseenter:鼠标移入元素触发,不支持冒泡。
mouseleave:鼠标移出元素时触发,不支持冒泡。
Event对象
Event对象用来描述JavaScript的事件,它主要作用于IE和NN4以后的各个浏览器版本中。Event对象代表事件状态,如事件发生的元素,键盘状态,鼠标位置和鼠标按钮状态。一旦事件发生,便会生成event对象,如单击一个按钮,浏览器的内存中就产生相应的event对象。
Event对象属性
方法 | 概述 |
---|---|
event.pageX | 鼠标相对于文档的左边缘的位置。 |
event.pageY | 鼠标相对于文档的顶部的位置。 |
event.target | 最初触发事件的DOM元素。 |
event.currentTarget | 在事件冒泡阶段中的当前DOM元素 |
event.delegateTarget | 当currently-called的jQuery事件处理程序附加元素。 |
event.relatedTarget | 在事件中涉及的其它任何DOM元素。 |
event.data | 当前执行的处理器被绑定的时候,包含可选的数据传递给jQuery.fn.bind。 |
event.type | 当事件被触发时此属性用于返回当前触发事件的事件类型。 |
event.timeStamp | 属性返回事件触发时距离1970年1月1日的毫秒数。 |
event.which | 针对键盘和鼠标事件,这个属性能确定你到底按的是哪个键或按钮。 |
event.namespace | 当事件被触发时此属性包含指定的命名空间。 |
event.result | 这个属性包含了当前事件最后触发的处理函数的返回值,除非值是 undefined 。 |
event.metaKey | metaKey属性用于指示事件触发时是否按下了Meta键。 |
说明:
event.target:这是注册事件时的对象,或者它的子元素。通常用于比较 event.target 和 this 来确定事件是不是由于冒泡而触发的。经常用于事件冒泡时处理事件委托。
在HTML文档中,我们为
元素绑定点击事件(“click”),由于DOM元素的事件冒泡机制,我们点击
元素内的一个元素就可以触发
元素上绑定的click事件。target属性就用于返回最初触发事件的DOM元素,也就是本例中的元素。(currentTarget属性始终返回的都是该
元素)
event.delegateTarget:该属性在.delegate()或者.on()委派事件非常有用,事件处理程序属于正在处理的元素的祖先元素,可以在委派时识别与删除事件处理程序。
对于非授权的事件处理程序,直接连接到一个元素,event.delegateTarget 总是等价于event.currentTarget.
event.delegateTarget属性的返回值是Element类型,返回”受委托”绑定当前事件处理函数的的DOM元素。
// 为id为element的元素中的所有span元素绑定click事件
$("#element").on( "click", "span", function(event){
// event.delegateTarget 就是id为element的DOM元素
// this 就是当前触发事件的span元素
alert( event.delegateTarget === this); // false
} );
// 为id为element的元素中的所有span元素绑定click事件
$("#element span").bind( "click", function(event){
// event.delegateTarget 就是当前触发事件的span元素
// this 就是当前触发事件的span元素
alert( event.delegateTarget === this ); // true
} );
event.relatedTarget:
relatedTarget属性的返回值是Element类型,返回当前事件涉及到的其他DOM元素(如果存在的话)。
对于 mouseout 事件,它指向被进入的元素;对于 mousein 事件,它指向被离开的元素。
如果当前事件没有涉及到其他元素,则返回null或undefined(视情况而定)。
event.type:
例如:如果触发的是单击事件,则返回”click”;如果是双击事件,则返回”dblclick”;如果是获取焦点事件,则返回”focus”。
该属性通常用于为多个事件类型绑定了同一个事件处理函数的jQuery代码中。
event.timeStamp:
这可以很方便的检测某个jQuery函数的性能。
请注意:在火狐浏览器中,由于浏览器自身的bug问题,该属性无法正确返回触发事件的时间值。
event.which:
event.which 将 event.keyCode 和 event.charCode 标准化了。推荐用 event.which 来监视键盘输入。
适用的事件类型主要有键盘事件:keypress、keydown、keyup,以及鼠标事件:mouseup、mousedown。
在mousedown、mouseup事件中,鼠标按钮映射代码对应表(相当于event.button):
event.which属性值 | 对应的鼠标按钮 |
---|---|
1 | 鼠标左键 |
2 | 鼠标中键(滚轮键) |
3 | 鼠标右键 |
在keypress事件中,event.which属性返回的是输入的字符的Unicode值(相当于event.charCode):
event.which属性值 | 对应的输入字符 |
---|---|
48-57 | 输入字符0-9 |
65-90 | 输入字符A-Z |
97-122 | 输入字符a-z |
在keydown、keyup事件中,event.which属性返回的是对应按键的映射代码值(相当于event.keyCode)。以下是常用的键盘按键映射代码的对应表:
event.which属性值 | 对应的输入字符 |
---|---|
8 | Backspace键 |
9 | Tab键 |
13 | Enter键 |
16 | Shift键 |
17 | Ctrl键 |
20 | Alt键 |
20 | Caps Lock键(大小写锁定) |
27 | Esc键 |
33 - 36 | 对应按键 PageUp、PageDown、End、Home |
37 - 40 | 对应按键 左、上、右、下(方向键) |
45 - 46 | 对应按键 Insert、Delete |
48 - 57 | 对应按键 0 - 9(非小键盘) |
65 - 90 | 对应按键 A - Z |
91 | Windows键 |
96 - 105 | 对应按键 0 - 9(小键盘) |
106、107、109、110、111 | 对应按键*、+、-、.、/(小键盘) |
112 - 123 | 对应按键 F1 - F12 |
// 为当前文档绑定keydown和mousedown两种事件
// 检测鼠标按下了那些键
// 检测键盘按下了那些字母按键
$(document).bind("keydown mousedown", function(event){
var msg = '';
if( event.type == "mousedown" ){ // 鼠标按下事件
var map = {"1": "左", "2":"中", "3":"右"};
msg = '你按下了鼠标[' + map[event.which] + ']键';
}else{ // 键盘按下事件
if(event.which >= 65 && event.which <= 90){
msg = '你按下了键盘[' + String.fromCharCode(event.which) + ']键';
}
}
if(msg){
$("#msg").prepend( msg + '<br>');
}
});
event.namespace:
当需要为同一个元素、同一种事件类型绑定多个事件处理函数时,一般情况下,触发某个事件,就会触发执行与之对应的所有事件处理函数;解除某种类型的事件绑定,就会解除该事件类型绑定的所有事件处理函数。
jQuery中的事件函数可以在绑定事件处理函数时,为每个事件类型定义一个或多个命名空间。使用命名空间,我们就可以只触发执行指定命名空间下的事件处理函数,或者只移除指定命名空间下绑定的事件处理函数。
<p>CodePlayer</p>
<script type="text/javascript">
// 事件处理函数,弹出警告框并显示命名空间
function handler( event ){
alert( event.namespace );
}
var $p = $("p");
// A:为所有p元素绑定click事件,定义在abc和foo两个命名空间下
$p.on( "click.abc.foo", handler );
// B:为所有p元素绑定click事件,定义在test命名空间下
$p.on( "click.test", handler );
// C:为所有p元素绑定click事件,定义在new和foo两个命名空间下
$p.on( "click.new.foo", handler );
// 执行所有的click事件处理函数,不限定命名空间 (触发A、B、C)
$p.trigger( "click" ); // ""
// 执行定义在abc命名空间下的click事件处理函数 (触发A)
$p.trigger( "click.abc" ); // "abc"
// 执行定义在foo命名空间下的click事件处理函数 (触发A和C)
$p.trigger( "click.foo" ); // "foo"
// 执行同时定义在foo和abc命名空间下的click事件处理函数 (触发A)
$p.trigger( "click.foo.abc" ); // "abc.foo"
// 执行定义在test命名空间下的click事件处理函数 (触发C)
$p.trigger( "click.test" ); // "test"
// 移除所有定义在foo命名空间下的click事件处理函数
$p.off( "click.foo" );
</script>
event.result:
如果为DOM元素的同一事件类型绑定了多个事件处理函数,你可以使用result属性获取上一个事件处理函数执行的返回值。
例如,你为DOM元素的”click”事件按照顺序绑定了A、B、C三个事件处理函数,你可以在事件处理函数B中获取A的返回值,在C中获取B的返回值。
$("#myForm").submit( function(event) {
// 验证文本框uid的输入是否有效
if( !$("#uid").val() ){
alert("uid不能为空!");
return false;
}
if( !$("#pwd").val() ){
alert("pwd不能为空!");
return false;
}
return true;
} );
$("#myForm").submit( function(event) {
// 如果前面的表单验证返回false,无法继续验证,直接返回false
if( event.result === false){
return false;
}
// 验证文本框mail的输入是否有效
if( !$("#mail").val() ){
alert("mail不能为空!");
return false;
}
return true;
} );
event.metaKey:大多数键盘上并不存在Meta键,该键存在于MIT计算机、Mac计算机或Sun公司的一些计算机键盘上。
metaKey属性的返回值是Boolean类型,返回表示是否按下Meta键的布尔值。如果按下,则返回true,否则返回false。
Event对象方法
方法 | 概述 |
---|---|
event.preventDefault() | 阻止默认事件行为的触发。 |
event.isDefaultPrevented() | 根据事件对象中是否调用过 event.preventDefault() 方法来返回一个布尔值。 |
event.stopPropagation() | 防止事件冒泡到DOM树上,也就是不触发任何前辈元素上的事件处理函数。 |
event.isPropagationStopped() | 根据事件对象中是否调用过 event.stopPropagation() 方法来返回一个布尔值。 |
event.stopImmediatePropagation() | 阻止剩余的事件处理函数执行并且防止事件冒泡到DOM树上。 |
event.isImmediatePropagationStopped() | 根据事件对象中是否调用过 event.stopImmediatePropagation() 方法来返回一个布尔值。 |
说明:
event.preventDefault():
在HTML文档中,当我们触发某些DOM元素的特定事件时,可以执行该元素的默认行为。比如链接的click事件:当我们点击一个链接时,就会跳转到指定的URL。再比如:表单元素的submit事件,当我们触发表单的提交事件时,就可以提交当前表单。
使用preventDefault()函数可以阻止该元素的默认行为。
$("a").click( function(event){
if( !confirm("你确定要删除?") ){
event.preventDefault(); // 阻止链接默认的URL跳转行为
// return false; // 函数的返回值为false,也可以起到阻止默认行为的效果
}
} );
$("form").submit( function(event){
if( !$("#username").val() ){
alert("username is required!");
event.preventDefault(); // 阻止默认的表单提交行为
// return false; // 函数的返回值为false,也可以起到阻止默认行为的效果
}
} );
event.isDefaultPrevented():
isDefaultPrevented()函数的返回值为Boolean类型,以指示是否已经阻止了当前触发事件的默认行为。如果是,则返回true,否则返回false。
$("a").click( function(event){
alert( event.isDefaultPrevented() ); // false
event.preventDefault();
alert( event.isDefaultPrevented() ); // true
} );
event.stopPropagation():用于阻止当前事件在DOM树上冒泡。
根据DOM事件流机制,在元素上触发的大多数事件都会冒泡传递到该元素的所有祖辈元素上,如果这些祖辈元素上也绑定了相应的事件处理函数,就会触发执行这些函数。
使用stopPropagation()函数可以阻止当前事件向祖辈元素的冒泡传递,也就是说该事件不会触发执行当前元素的任何祖辈元素的任何事件处理函数。
该函数只阻止事件向祖辈元素的传播,不会阻止该元素自身绑定的其他事件处理函数的函数。event.stopImmediatePropagation()不仅会阻止事件向祖辈元素的传播,还会阻止该元素绑定的其他(尚未执行的)事件处理函数的执行。
此外,由于live()函数并不是将事件处理函数直接绑定到自己身上,而是”委托”绑定到祖辈元素上,由祖辈元素来触发执行。live()函数会先一次性冒泡到文档的顶部,然后为符合条件的元素触发事件。因此,stopPropagation()函数无法阻止live事件的冒泡。
同样地,delegate()函数也是”委托事件函数”,只有事件冒泡传递到”受委托”的祖辈元素才会被触发执行。因此,stopPropagation()函数无法阻止该元素到”受委托”的祖辈元素之间的事件冒泡。
// 为所有div元素的click事件绑定处理函数
$("div").click( function(event){
alert("div-click");
} );
// 为所有p元素的click事件绑定处理函数
$("p").click( function(event){
alert("p-click");
} );
// 为div元素内的所有button元素的click事件绑定处理函数
$("div").live("click", ":button", function(event){
alert("button-click");
event.stopPropagation();
} );
// 点击按钮,所有事件处理函数都会执行
// 因为live()函数先直接冒泡到document,然后再来触发事件,因此它无法阻止事件冒泡(执行函数时都已经冒泡完毕,当然无法阻止)
event.isPropagationStopped():
函数用于判断是否已经调用过event.stopPropagation()函数
event.stopImmediatePropagation():
根据DOM事件流机制,在元素上触发的大多数事件都会冒泡传递到该元素的所有祖辈元素上,如果这些祖辈元素上也绑定了相应的事件处理函数,就会触发执行这些函数。
使用stopImmediatePropagation()函数可以阻止当前事件向祖辈元素的冒泡传递,也就是说该事件不会触发执行当前元素的任何祖辈元素的任何事件处理函数。
此外,与event.stopPropagation()函数相比,stopImmediatePropagation()函数还会阻止该元素剩余的其他事件处理函数的执行。
此外,由于live()函数并不是将事件处理函数直接绑定到自己身上,而是”委托”绑定到祖辈元素上,由祖辈元素来触发执行。live()函数会先一次性冒泡到文档的顶部,然后为符合条件的元素触发事件。因此,stopImmediatePropagation()函数无法阻止live事件的冒泡。
同样地,delegate()函数也是”委托事件函数”,只有事件冒泡传递到”受委托”的祖辈元素才会被触发执行。因此,stopImmediatePropagation()函数无法阻止该元素到”受委托”的祖辈元素之间的事件冒泡。
// 为所有p元素绑定click事件
$("p").click( function(event){
alert("p-click");
} );
// 为所有button元素的click事件绑定第一个事件处理函数
$(":button").click( function(event){
alert("button-click-1");
// 阻止事件冒泡到DOM树上,并阻止剩余的事件处理函数的执行
// 只执行button-click-1,如果注释掉该行,将执行button-click-1、button-click-2和p-click
// 如果换成event.stopPropagation() 将执行button-click-1和button-click-2
event.stopImmediatePropagation();
} );
// 为所有button元素的click事件绑定第二个事件处理函数
$(":button").click( function(event){
alert("button-click-2");
} );
event.isImmediatePropagationStopped():
根据事件对象中是否调用过 event.stopImmediatePropagation() 方法来返回一个布尔值。
// 为所有p元素绑定click事件
$("p").click( function(event){
alert("p-click");
} );
// 为所有button元素的click事件绑定第一个事件处理函数
$(":button").click( function(event){
alert("button-click-1");
alert( event.isImmediatePropagationStopped() ); // false
event.stopImmediatePropagation();
alert( event.isImmediatePropagationStopped() ); // true
} );
// 为所有button元素的click事件绑定第二个事件处理函数
$(":button").click( function(event){
alert("button-click-2");
} );