一、页面加载事件
主要两种类型:
1、window 的load 事件
页面载入完成时触发
jQuery(window).bind("load",function() {
$("#signinForm").submit(checkForm);
});
2、DOMContentLoaded
DOM构建完成时触发这个事件,这是图片和样式可能还未完成加载。也就是说这个时间一定会在用户和页面交互之前触发。
并不是所有浏览器都支持DOMContentLoaded,因此jQuery将它融入到了ready()函数,这个函数兼容各个浏览器。
jQuery.ready(function($)){
$("#myForm").bind("submit", function(){
/*...*/
});
});
更简洁的写法,可以不用ready()函数而直接将回调函数写入jQuery 对象。
jQuery(function($){
//当页面内容可用时调用
});
二、切换上下文
调用事件回调函数时上下文会发生切换,从局部上下文切换成目标元素上下文:
new function(){
this.appName = "wem";
document.body.addEventListener("click", function(e){
// 上下文发生改变,因此appName 是undefined
alert(this.appName);
}, false);
};
要想保持原有的上下文,需要将回调函数包装进一个匿名函数,然后用一个引用指向它。
jQuery中提供的proxy函数可解决:
new function(){
this.appName = "wem";
$("#btnSubmit").click($.proxy(function(){
//这里的this指向proxy函数参数中的this
alert(this.appName);
}, this));
};
proxy函数的大致实现方式:
var proxy = function(func, thisObject){
return (function() {
return func.apply(thisObject, arguments);
});
};
三、委托事件
直接给父元素绑定事件监听,用来检测在其子元素内发生的事件。
能减少事件监听的数量,改善代码性能 。
所有为元素动态添加的子元素都具有事件监听。
// 不要这样做,这样会给每个li 元素都添加事件监听(非常浪费)
$("ul li").click(function(){ /* ... */ });
1、原生js的做法:
// 在ul 列表上做了事件委托
list.addEventListener("click", function(e){
if (e.target.tagName == "LI") {
/* ... */
return false;
}
}, false);
2、jquery的实现:
// 这样只会添加一个事件监听
// 在页面载入完成后添加的li 节点同样可以触发点击事件的回调
$("ul").delegate("li", "click", function(e){
/* ... */
return false;
});
四、自定义事件
自定义事件是很好的解耦代码的处理方法,jQuery 的很多插件都是利用自定义事件来实现。
和内置事件一样,自定义事件同样会沿着DOM 树做冒泡。
1、原生js的做法:
var myEvent = {};
//创建事件
myEvent.createEvent = function (eventStr, datatype, data) {
var e;
if ( document.createEvent) {
e = document.createEvent('Events'); //W3C创建新事件的写法
e.initEvent(eventStr, true , false);
} else if (document.createEventObject) {
e = document.createEventObject(); //IE的创建新事件的写法
} else {
return null;
}
e.datatype = datatype;
e.data = data;
return e;
};
//触发事件
myEvent.send = function (target, eventStr, datatype, data) {
if ( typeof target == 'string') {
target = document.getElementById(target);
}
var e = this.createEvent(eventStr, datatype, data);
if(e == null) {
return;
}
if (target.dispatchEvent) {
target.dispatchEvent(e);
} else if (target.fireEvent) {
target.fireEvent('on' + eventStr, e);
}
};
//绑定事件
myEvent.receive = function (target, eventStr, handler) {
if (typeof target == 'string') {
target = document.getElementById(target);
}
if (target.addEventListener) {
target.addEventListener(eventStr, handler, false);
} else if( target.attachEvent) {
target.attachEvent('on' + eventStr, handler); //IE
}
};
myEvent.receive("menuList", "event.chen.menuClick", function(e) {
alert(e.data + "被点击!");
});
$("#menuList").click(function(e) {
if (e.target.tagName == "LI") {
myEvent.send("menuList", "event.chen.menuClick", "string", e.target.innerHTML);
}
});
2、jquery的实现:
$("#menuList").bind("event.chen.menuClick", function(e, data){
alert(data.menuName + "被点击!");
});
$("#menuList").delegate("li", "click", function(e){
$("#menuList").trigger("event.chen.menuClick", {menuName:e.target.innerHTML});
});
事件并不是只能被绑定到DOM元素上,我们可以将其绑定到自定义的对象上,从而开发出类似于JAVA的事件驱动框架,又称为发布/订阅模式。
发布者向某个信道发布一条消息,订阅者绑定这个信道,当有消息发布至信道时就会接收到一个通知。发布者和订阅者是完全解耦的,甚至彼此可以并不知晓对方的存在。