事件对象
event 对象还包含很多有用的属性。W3C 范中包含的大部分属性都列在下面,更多信息参照完整的标准规范。
事件类型:
- bubbles :布尔值,表示事件是否通过DOM 以冒泡形式触发。
事件发生时,反映当前环境信息的属性:
- button :表示(如果有)鼠标所按下的按钮。
- ctrlKey :布尔值,表示Ctrl 键是否按下。
- altKey :布尔值,表示Alt 键是否按下。
- shiftKey :布尔值,表示Shift 键是否按下。
- metaKey :布尔值,表示Meta 键是否按下。
表示键盘事件的属性:
- isChar :布尔值,表示当前按下的键是否表示一个字符。
- charCode :表示当前按键的unicode 值(仅对keypress 事件有效)。
- keyCode :表示非字符按键的unicode 值。
- which :表示当前按键的unicode 值,不管当前按键是否表示一个字符。
事件发生时的环境参数:
- pageX,pageY :事件发生时相对于页面(如viewport 区域)的坐标。
- screenX,screenY :事件发生时相对于屏幕的坐标。
和事件相关的元素:
- currentTarget :事件冒泡阶段所在的当前DOM 元素。
- target,originalTrget :原始的DOM 元素。
- relatedTarget :其他和事件相关的DOM 元素(如果有的话)。
不同的浏览器对这些属性的兼容性也不同,尤其是那些不兼容W3C 的浏览器。
事件库
手动处理众多浏览器的差异性吃力不讨好。jQuery 的API 提供了bind()
函数用来跨浏览器绑定事件监听。在一个jQuery 实例上调用此函数,传入事件名称和回调函数:
jQuery("#element").bind(eventName, handler);
给一个元素注册点击事件:
jQuery("#element").bind("click", function(event) {
// ...
});
jQuery 提供了一些常用事件的快捷方法,比如click
、submit
和mouseover
:
$("#myDiv").click(function(){
// ...
});
注意: 使用这个方法之前要确保DOM 元素是存在的。例如,应当在页面载入完成后绑定事件,因此需要绑定window 的load
事件,然后添加监听:
jQuery(window).bind("load", function() {
$("#signinForm").submit(checkForm);
});
比监听window 的load 事件更好的方法,即DOMContentLoaded
。当DOM 构建完成时触发这个事件,这时图片和样式表可能还未加载完毕。这也就是说这个事件一定会在用户和页面产生交互之前触发。并不是所有的浏览器都支持DOMContentLoaded,因此jQuery 将它融入了ready() 函数,这个函数是兼容各个浏览器的:
jQuery.ready(function($)){
$("#myForm"). bind("submit", function(){ /*...*/});
});
实际上,可以不用ready() 函数而直接将回调函数写入jQuery 对象。
jQuery(function($){
// 当页面内容可用时调用
});
切换上下文
关于事件有一点经常让人感到迷惑就是调用事件回调函数时上下文的切换。当使用浏览器内置的addEventListener() 时,上下文从局部变量切换为目标HTML 元素:
new function(){
this.appName = "wem";
document.body.addEventListener("click", function(e){
// 上下文发生改变,因此appName 是undefined
alert(this.appName);
}, false);
};
要想保持原有的上下文,需要将回调函数包装进一个匿名函数,然后定义一个引用指向它。即使用代理函数来保持当前的上下文。这在jQuery 中也是一种很常用的模式,包括一个proxy()
函数,只需将指定的上下文传入函数即可:
$("signinForm").submit($.proxy(function(){ /* ... */ }, this));
自定义事件
除了浏览器内置的事件之外,也可以触发和绑定自定义事件。这是架构库的一个好方法——也是jQuery 的大多数插件所使用的模式。大多数浏览器厂商均未实现W3C 标准中的自定义事件,可以使用诸如jQuery 或Prototype 的类库来使用这个特性。jQuery 中可以使用trigger()
函数来触发自定义事件。可以通过命名空间的形式来管理事件名称,命名空间中的单词用点号分隔,比如:
// 绑定自定义事件
$(".class").bind("refresh.widget",function(){});
// 触发自定义事件
$(".class").trigger("refresh.widget");
通过给trigger() 传入一个额外的参数来给事件处理程序传入数据。数据会以附加参数 的形式带入回调:
$(".class").bind("frob.widget", function(event, dataNumber){
console.log(dataNumber);
});
$(".class").trigger("frob.widget", 5);
和内置事件一样,自定义事件同样会沿着DOM 树做冒泡。
(公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。)