到此,一套完整的事件机制就已经完成了,完整代码如下:
function CustomEvent() { this._events = {}; } CustomEvent.prototype = { constructor: CustomEvent, /** * 绑定事件 * * @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; }, /** * 触发事件 * * @param {String} type 触发事件的名称 * @param {Anything} 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, scope, event = Object.assign({ // 事件类型 type: type, // 绑定的源 origin: this, // scope 为 this 或用户指定的上下文, // 是否取消 cancel: false }, data); if (!eventArr) return event; for (var i = 0, l = eventArr.length; i < l; ++i) { fn = eventArr[i][0]; scope = eventArr[i][1]; if (scope) { event.scope = scope; fn.call(scope, event); } else { event.scope = this; fn(event); } } return event; }, /** * 取消绑定一个事件 * * @param {String} type 取消绑定的事件名称 * @param {Function} fn 要取消绑定的事件处理函数,不指定则移除当前事件类型下的全部处理函数 * @returns 当前实例对象 */ off: function (type, fn) { type = type.toLowerCase(); var eventArr = this._events[type]; if (!eventArr || !eventArr.length) return this; if (!fn) { this._events[type] = eventArr = []; } else { for (var i = 0; i < eventArr.length; ++i) { if (fn === eventArr[i][0]) { eventArr.splice(i, 1); // 1、找到后不能立即 break 可能存在一个事件一个函数绑定多次的情况 // 删除后数组改变,下一个仍然需要遍历处理! --i; } } } return this; }, /** * 绑定一个只执行一次的事件 * * @param {String} type 事件类型 * @param {Function} fn 事件处理函数 * @param {Object} scope 要为事件处理函数绑定的执行上下文 * @returns 当前实例对象 */ one: function (type, fn, scope) { var that = this; function nfn() { // 执行时 先取消绑定 that.off(type, nfn); // 再执行函数 fn.apply(scope || that, arguments); } this.on(type, nfn, scope); return this; } };
内容版权声明:除非注明,否则皆为本站原创文章。