jQuery原生框架-----------------事件

时间:2023-03-09 17:37:58
jQuery原生框架-----------------事件

jQuery.extend({

// 绑定事件
addEvent: function( ele, type, fn ) {

// ele不是DOM,type不是字符串,fn不是函数,打包打走
if( !jQuery.isDOM( ele ) || !jQuery.isString( type ) || !jQuery.isFunction( fn ) ) {
return false;
}

// 兼容处理
if( ele.addEventListener ) {
ele.addEventListener( type, fn );
}else {
ele.attachEvent( 'on' + type, fn );
}
},

// 移除事件
removeEvent: function( ele, type, fn ) {

// ele不是DOM,type不是字符串,fn不是函数,打包打走
if( !jQuery.isDOM( ele ) || !jQuery.isString( type ) || !jQuery.isFunction( fn ) ) {
return false;
}

// 兼容处理
if( ele.removeEventListener ) {
ele.removeEventListener( type, fn );
}else {
ele.detachEvent( 'on' + type, fn );
}
}
});

jQuery.fn.extend({

// 绑定事件
on: function( type, fn ) {
/*
* 实现思路:
* 1、第一次给元素绑定某事件时,给元素按照事件类型初始化一个存储对应事件处理函数的数组
* 2、然后把fn存储进去,再给元素调用addEvent静态方法绑定对应的事件,
* 2.1、这个事件触发时,遍历对应事件处理函数的数组,按照顺序执行他们
* 2.2、同时要改变函数执行时内部的this为绑定者
* 2.3、同时还要把event事件对象传给函数供其使用
* 3、以后再给这个元素绑定已经绑过事件,只需把事件处理函数push到对应的数组中即可。
* 4、链式编程返回this
* */

// 遍历所有元素
return this.each( function() {

var self = this;

// 如果元素之间没有event_cache,那么就初始化一下,有了继续使用之前的。
self.event_cache = self.event_cache || {};

// 判断元素有没有对应事件类型的数组,
// 如果有则直接把fn添加进去即可
if( self.event_cache[ type + '_cache' ] ) {
self.event_cache[ type + '_cache' ].push( fn );
}

// 没有就是第一次绑定该事件
else {

// 先给元素初始化对应的事件数组
self.event_cache[ type + '_cache' ] = [];
self.event_cache[ type + '_cache' ].push( fn );

// 绑定事件,事件触发时,遍历对应的事件数组,执行里面存储的每一个函数
jQuery.addEvent( this, type, function( e ) {

// 遍历对应的事件数组
jQuery.each( self.event_cache[ type + '_cache' ], function() {

// 这里的this指向每一个遍历到的事件处理函数
this.call( self, e );
});
});
}
});
},

// 移除事件
off: function( type, fn ) {
/*
* 实现思路:
* 1、遍历所有元素,如果元素有event_cache再进行下一步处理
* 2、如果没有传参,清空event_cache对象中存储的每一个数组
* 3、如果传了一个参数,清空event_cache对象中指定的数组
* 4、如果传了两个参数,清除event_cache对象中指定数组中指定的函数
* 5、链式编程返回this
* */
var argLen = arguments.length;

return this.each( function() {

var arr = null;
var self = this;

// 如果有event_cache这个对象,说明元素帮过事件,
// 进一步根据参数个数做移除处理。
if( this.event_cache ) {

// 清除所有事件数组
if( argLen === 0 ) {
jQuery.each( this.event_cache, function( key, arr ) {
self.event_cache[ key ] = [];
});
}

// 清除指定的事件数组
else if( argLen === 1 ) {
this.event_cache[ type + '_cache' ] = [];
}

// 清除指定的事件数组中指定的函数
else if( argLen === 2 ) {
arr = this.event_cache[ type + '_cache' ];
for( var i = arr.length - 1; i >= 0; i-- ) {
if( arr[ i ] === fn ) {
arr.splice( i, 1 );
}
}
}
}
});
}
});

// 给原型添加一些事件绑定的简写方式
var events = [ 'click', 'change', 'resize', 'mousedown', 'mouseout', 'mouseenter' ];
jQuery.each( events, function( i, eventName ) {
jQuery.fn[ eventName ] = function( fn ) {
return this.on( eventName, fn );
}
});