那么事件绑定要干什么呢,其实很简单,事件绑定只用将相应的事件名称和事件处理函数记录下来即可。
我的实现如下:
{
/**
* 绑定事件
*
* @param {String} type 事件类型
* @param {Function} fn 事件处理函数
* @param {Object} scope 要为事件处理函数绑定的执行上下文
* @returns 当前实例对象
*/
on: function (type, fn, scope) {
if (type + '' !== type) {
console && console.error && console.error('the first argument type is requird as string');
return this;
}
if (typeof fn != 'function') {
console && console.error && console.error('the second argument fn is requird as function');
return this;
}
type = type.toLowerCase();
if (!this._events[type]) {
this._events[type] = [];
}
this._events[type].push(scope ? [fn, scope] : [fn]);
return this;
}
}
由于一种事件可以绑定多次,执行时依次执行,所有事件类型下的处理函数存储使用的是数组。
事件触发
事件触发的基本功能就是去执行用户所绑定的事件,所以只用在事件触发时去检查有没有指定的执行函数,如果有则调用即可。
另外事件触发实际就是用户指定的处理函数执行的过程,而能进行很多个性化操作也都是在用户指定的事件处理函数中进行的,因此仅仅是执行这个函数还不够。还必须为当前函数提供必要的信息,如点击事件中有当前被点击的元素,键盘事件中有当前键的键码,上传开始和上传完成中有当前文件的信息。
因此事件触发时,事件处理函数的实参中必须包含当前事件的基本信息。
除此之外通过用户在事件处理函数中的操作,可能需要调整之后的信息,如keydwon事件中用户可以禁止此键的录入,文件上传前,用户在事件中取消此文件的上传或是修改一些文件信息。因此事件触发函数应返回用户修改后的事件对象。
我的实现如下:
{
/**
* 触发事件
*
* @param {String} type 触发事件的名称
* @param {Object} data 要额外传递的数据,事件处理函数参数如下
* event = {
// 事件类型
type: type,
// 绑定的源,始终为当前实例对象
origin: this,
// 事件处理函数中的执行上下文 为 this 或用户指定的上下文对象
scope :this/scope
// 其他数据 为fire时传递的数据
}
* @returns 事件对象
*/
fire: function (type, data) {
type = type.toLowerCase();
var eventArr = this._events[type];
var fn,
// event = {
// // 事件类型
// type: type,
// // 绑定的源
// origin: this,
// // scope 为 this 或用户指定的上下文,
// // 其他数据
// data: data,
// // 是否取消
// cancel: false
// };
// 上面对自定义参数的处理不便于使用 将相关属性直接合并到事件参数中
event = $.extend({
// 事件类型
type: type,
// 绑定的源
origin: this,
// scope 为 this 或用户指定的上下文,
// 其他数据
// data: data,
// 是否取消
cancel: false
}, data);
if (!eventArr) {
return event;
}
for (var i = 0, l = eventArr.length; i < l; ++i) {
fn = eventArr[i][0];
event.scope = eventArr[i][1] || this;
fn.call(event.scope, event);
}
return event;
}
}
内容版权声明:除非注明,否则皆为本站原创文章。
