JavaScript实现自定义对象的自定义事件

前言:

大家都知道,在使用JavaScript可以很方便的使用addEventListener函数给DOM对象快速绑定一个或多个事件侦听器。

我们又如何在JavaScript的自定义对象中使用此方法并触发事件呢?这就是本章节的核心内容了。

目的:

现在有一个需求,要求“a对象”能够让“b对象“做一系列动作。

分析后我们得知。首先,”b对象“有一个固定名称作为入口让a对象调用,并且这个入口可以自动检索所有符合这个动作要求的函数并依次触发。

实现:

好的,经过以上内容我们可以简单的了解到为什么我们需要自定义事件了。

接下来我们来用代码具体实现一下。

function CursomObject (table) {/// <summary>这是一个自定义对象类型</summary>/// <param name="table" type="Object" optional="true">要添加的函数及属性表</param>// 这里要存放我们的自定义事件// 因为是一个表,,所以我们使用Object类型this._events = {};// 得到函数及属性表中的内容for (var i in table) this[i] = table[i];}上面这段代码定义了一个CursomObject类型,这将作为下面所做操作的基础。

CursomObject.prototype.addEventListener = function (type, listener, capture) {/// <summary>添加事件侦听器</summary>/// <param name="type" type="String">事件类型</param>/// <param name="listener" type="Function">触发的函数</param>/// <param name="capture" type="Boolean" optional="true">是否在捕获阶段触发(这里只是做了顺序排列)</param>// 判断一下传入的参数是否符合规格if (typeof type !== "string" || typeof listener !== "function") return this;// 缓存符合条件的事件列表var list = this._events[type];// 判断是否已经有该类型事件,若没有则添加一个新数组if (typeof list === "undefined") list = (this._events[type] = []);/* 判断插入函数的位置 */if (!!capture) list.push(listener);else list.insert(0, listener);return this;};至此,我们已经实现了一个简单的事件监听器的添加功能了。

这里需要注意一下,list.insert中的insert函数在JavaScript的Array中是不存在的,我们将在下面的扩展函数中找到。

另外,return this; 则是为了方便链式编程【详情请参阅”附录1“】CursomObject.prototype.removeEventListener = function (type, listener, capture) {/// <summary>移除事件侦听器</summary>/// <param name="type" type="String">事件名称</param>/// <param name="listener" type="Function">触发的函数</param>/// <param name="capture" type="Boolean">是否在捕获阶段触发</param>// 判断一下传入的参数是否符合规格if (typeof type !== "string" || typeof listener !== "function") return this;// 缓存符合条件的事件列表var list = this._events[type];// 若没有绑定过此类事件则不需要做处理if (typeof list === "undefined") return this;for (var i = 0, len = list.length; i < len; i++) {// 通过循环判断来确定事件列表中存在要移除的事件侦听函数if (list[i] == listener) {// 找到后将此侦听函数从事件列表中移除list.remove(i);break;}}return this;};以上过程简单明了,一个循环搞定问题。

同时这个也需要注意,JavaScript中的Array中是不存在remove函数的,同样在下面扩展函数中会出现。

CursomObject.prototype.fireEvent = function (type, e) {/// <summary>触发事件</summary>/// <param name="type" type="String">事件名称</param>/// <param name="e" type="Object">附加参数对象</param>// 若存在DOM0用法的函数,则触发this["on" + type.toLowerCase()] && this["on" + type.toLowerCase()].call(this, e);// 缓存符合条件的事件列表var list = this._events[type];// 若事件列表中没有内容则不需要做处理if (!list || list.length <= 0) return this;// 阻止事件冒泡开关var isStop = false;// 模拟事件对象window.event = { stopPropagation: function () { isStop = true; } };e.stopPropagation = window.event.stopPropagation;for (var i = 0, len = list.length; i < len; i++) {// 通过循环触发符条件的事件列表中存在的所有事件侦听函数// 若函数内返回false或事件内调用了event.stopPropagation函数则阻止接下来的所有调用if (list[i].call(this, e) === false || isStop) break;}return this;};注释已经说的很清楚了,这里就不再累述。

那么至此就主体就已经完成了。下面放出扩展函数。

Array.prototype.insert = function (index, value) {/// <summary>插入项</summary>/// <param name="index" type="Number">索引</param>/// <param name="value" type="Object">元素</param>/// <returns type="Array" />if (index > this.length) index = this.length;if (index < -this.length) index = 0;if (index < 0) index = this.length + index;for (var i = this.length; i > index; i–) {this[i] = this[i – 1];}this[index] = value;return this;};Array.prototype.remove = function (index) {/// <summary>移除项</summary>/// <param name="index" type="Number">索引</param>/// <returns type="Array" />if (isNaN(index) || index > this.length) return;this.splice(index, 1);};OK,已经全部完成了。

下面放出完整代码。

我没有值得分享的感伤爱情故事,

JavaScript实现自定义对象的自定义事件

相关文章:

你感兴趣的文章:

标签云: