在软件工程中,最可怕的一种情况便是某些事物变的不可控制,然后整个软件变的复杂庞大难以维护。
最近遇到一个问题,页面DOM的监听事件开始变的混乱。你不能够清楚地知道一个DOM元素被注册了多少监听事件,以及有多少监听事件是重复的,还有你不能得知这个DOM元素将在何时被某一段JS监听处理块操纵。由此,这令我深思。如果将再次扩展或者添加新功能的时候,这项任务交给一另一位开发人员。会发生怎样的情景?
1、继续注册监听事件。
2、寻找出可能找出来的监听事件再扩展(并不能确定他会将它们全部找到,并理清它们的逻辑顺序)。
接下去,软件将向怎样的情景发展下去?
所以,我想到自己开发一个维护所有JS监听的框架。这个框架不能帮你处理掉你重复注册监听及操作DOM元素。而是让你能随时都能清楚这个监听运行时的各种日志信息。总结一下主要功能:
1、保存DOM元素到监听,任何时候你都可以清楚DOM元素变更情况。
2、将监听添加到块内,随时随地了解一个页面的某一块内有多少监听事件。
3、对每一个监听事件给定序列号,能够找出某一时间段内所有监听运行顺序。
4、每一个监听事件将输出性能报告,或者某一DOM元素的监听处理(一个或多个处理)性能报告。
/** * Created by ling on 2015/2/2. */ var _addEventListener = EventTarget.prototype.addEventListener, _removeEventListener = EventTarget.prototype.removeEventListener; var elements = []; /** * 获取当前系统时间 * @returns {number} */ var time = function () { return new Date().getTime(); }; /** * 递归出元素相对body位置 * @param node * @param count * @returns {*} */ var elementPosition = function (node, count) { if (node.tagName === 'BODY') { return count; } ++count; return elementPosition(node.parentNode, count); }; /** @param {string} type @param {EventListener|Function} listener @param {boolean} [useCapture] */ EventTarget.prototype.addEventListener = function (type, listener, useCapture, before, after) { var _this = this, sequence = 'Sequence: ' + time(); if (elements.length === 0) { elements.push(_this); } else { var length = elements.length, i = 0, is = false; for (; i < length; ++i) { if (elements[i] === _this && elementPosition(elements[i], 0) === elementPosition(_this, 0) && elements[i].nextSibling === _this.nextSibling) { is = true; break; } } if (!is) { elements.push(_this); } } console.log(elements.length); var handle = { handleEvent: function () { var start = time(); if (typeof before === 'function') this.call(before); if (typeof listener === 'function') { listener(); } if (typeof after === 'function') this.call(after); var end = time(); console.log(sequence); console.log('DOMElement:'); console.log(_this); console.log('Function:'); console.log(listener); console.log('Time consuming: ' + (end - start) + 'ms'); } }; return _addEventListener.call(this, type, handle, useCapture); }; /** @param {string} type @param {EventListener|Function} listener @param {boolean} [useCapture] */ EventTarget.prototype.removeEventListener = function (type, listener, useCapture) { console.log(this); console.log(type); console.log(listener); console.log(useCapture); return _removeEventListener.call(this, type, listener, useCapture); };