jQuery的Event模块非常强大。其功能远远比原生事件监听器强大许多,对同一个元素的监听只用一个eventListener,内部则是一个强大的观察者,根据匹配事件类型触发相应回调。jQuery不仅封装了兼容性差异,还提供了命名空间式注册注销事件,灵活的事件委托(事件代理),手动触发事件trigger以及自定义事件。因为jQuery提供的bind,delegate,live(1.9版本废除了)的功能都是通过on来适配的,所以这里只讲on,off,trigger。
1.注册事件$.fn.on方法
1 on: function(types, selector, data, fn, /*INTERNAL*/ one) { 2 var type, origFn; 3 4 // 添加多个事件注册 5 if (typeof types === "object") { 6 // ( types-Object, selector, data ) 7 if (typeof selector !== "string") { 8 // ( types-Object, data ) 9 data = data || selector; 10 selector = undefined; 11 } 12 // 为每个事件迭代 13 for (type in types) { 14 this.on(type, selector, data, types[type], one); 15 } 16 return this; 17 } 18 19 // 如果data和fn都为空,则将selector赋值给fn, 20 if (data == null && fn == null) { 21 // ( types, fn ) 22 fn = selector; 23 data = selector = undefined; 24 } else if (fn == null) { 25 if (typeof selector === "string") { 26 // ( types, selector, fn ) 27 fn = data; 28 data = undefined; 29 } else { 30 // ( types, data, fn ) 31 fn = data; 32 data = selector; 33 selector = undefined; 34 } 35 } 36 if (fn === false) { 37 fn = returnFalse; 38 } else if (!fn) { 39 return this; 40 } 41 42 // 如果只是一次性事件,则将fn从新包装 43 if (one === 1) { 44 origFn = fn; 45 fn = function(event) { 46 // 这里使用空的jq对象来解除事件绑定信息, 47 // 具体定位是通过event.handleObj和目标元素event.delegateTarget 48 jQuery().off(event); 49 // 执行原始的fn函数 50 return origFn.apply(this, arguments); 51 }; 52 // Use same guid so caller can remove using origFn 53 // 备忘信息 54 fn.guid = origFn.guid || (origFn.guid = jQuery.guid++); 55 } 56 // 统一调用jQuery.event.add方法添加事件处理 57 return this.each(function() { 58 jQuery.event.add(this, types, fn, data, selector); 59 }); 60 }