-
自定義事件
問題來源
JS經常在一個操作(可能是異步操作,也可能不是)執行完成之后才能繼續處理某些代碼,或者是在滿足一定條件的時候調用很多的組建,這個時候我們通常有兩種解決辦法。
第一種:采用回調的方式來實現這樣的功能,這樣的實現有個缺陷就是,當嵌套的時候,回調函數會一層套一層,很難應用到JS面向對象和模塊化的編程思想。
第二種:使用promiss對象來實現(await/synch本質上也是promiss)。
這兩種處理方式都可以實現以上的功能,我想說的是可以采用另外一種編程方式實現,即自定義事件。
自定義事件原理
自定義事件采用觀察者設計模式,當某個狀態發送變化時會通知所有事件處理者來處理這個變化的事件,自定義事件對象需要向外提供事件注冊的接口,並且在其內部滿足什么條件的時候應該觸發這些事件。
源代碼:
function costomEvent() { this.handlers = {}; } costomEvent.prototype = { constructor: costomEvent, addEvent: function (type, handler) { if (typeof handlers[type] === 'undefined') { this.handlers[type] = []; } this.handlers[type].push(handler); }, removeEvent: function (type, handler) { if (this.handlers[type] instanceof Array) { $.each(this.handlers[type], function (i) { if (this === handler) { this.handlers[type].splice(i, 1); return false; } }); } }, fire: function (event) { if (!event.target) { event.target = this; } if (this.handlers[event.type] instanceof Array) { $.each(this.handlers[event.type], function () { this(event); }) } } }
自定義事件優缺點
自定義事件會使編程變得更加簡潔明良,讓各模塊之間松散耦合,還能傳遞信息,減少回調函數的嵌套,但是自定義事件不好定位問題,容易產生意想不到的錯誤。
附件:
(function (window, $) { var muphy = Object.create({ isNull: function (data) { if (data === null || data === undefined) { return true; } if (typeof data === "String" && data.trim() === '') { return true; } if (data instanceof Array && data.length == 0) { return true; } return false; }, nvl: function (data, obj) { if (obj === 0) return 0; return data || obj || ''; }, each: function (obj, fun) { for (var key in obj) { if (fun.call(obj[key], key, obj[key]) === false) { break; } } }, addEvent: function (ele, type, handler) { if (ele.addEventListener) { ele.addEventListener(type, handler, false); } else if (ele.attachEvent) { ele.attachEvent("on" + type, handler); } else { ele["on" + type] = handler; } }, removeEvent: function (ele, type, handler) { if (ele.removeEventListener) { ele.removeEventListener(type, handler, false); } else if (ele.detachEvent) { ele.detachEvent("on" + type, handler); } else { ele["on" + type] = null; } }, _dragEvent: function (ele) { var drag = null, diffx = 0, diffy = 0, $e = null; if ($.isNull(ele)) return; if (!($e = $(ele))) return; $(document).bind("mousedown", handleEvent); $(document).bind("mousemove", handleEvent); //$(document).bind("mouseup",handleEvent); $.muphy.addEevent(document, "mouseup", handleEvent); function handleEvent(event) { event = event || window.event; var target = $e[0]; switch (event.type) { case "mousedown": if ($m.nvl(target.className).indexOf("draggable") > -1) { drag = target; diffx = event.clientX - target.offsetLeft; diffy = event.clientY - target.offsetTop; } break; case "mousemove": if (drag !== null) { drag.style.left = (event.clientX - diffx) + "px"; drag.style.top = (event.clientY - diffy) + "px"; } break; case "mouseup": drag = null; break; } } }, dragEvent: function () { var drag = null, diffx = 0, diffy = 0; $(document).unbind("mousedown", handleEvent); $(document).unbind("mousemove", handleEvent); $(document).unbind("mouseup", handleEvent); $(document).bind("mousedown", handleEvent); $(document).bind("mousemove", handleEvent); $(document).bind("mouseup", handleEvent); function handleEvent(event) { event = event || window.event; var target = event.target || event.srcElement; switch (event.type) { case "mousedown": if ($m.nvl(target.className).indexOf("draggable") > -1) { drag = target; diffx = event.clientX - target.offsetLeft; diffy = event.clientY - target.offsetTop; } break; case "mousemove": if (drag !== null) { drag.style.left = (event.clientX - diffx) + "px"; drag.style.top = (event.clientY - diffy) + "px"; } break; case "mouseup": drag = null; break; } } }, _costomEvent: function () { var handlers = {}; this.addEvent = function (type, handler) { if (typeof handlers[type] === 'undefined') { handlers[type] = []; } handlers[type].push(handler); } this.removeEvent = function (type, handler) { if (handlers[type] instanceof Array) { muphy.each(handlers[type], function (i) { if (this === handler) { handlers[type].splice(i, 1); return false; } }); } } this.fire = function (event) { if (!event.target) { event.target = this; } if (handlers[event.type] instanceof Array) { muphy.each(handlers[event.type], function () { this(event); }) } } }, costomEvent: function () { } }); (function (muphy) { muphy.costomEvent1.prototype = { constructor: muphy.costomEvent1, handlers: {}, addEvent: function (type, handler) { if (typeof this.handlers[type] === 'undefined') { this.handlers[type] = []; } this.handlers[type].push(handler); }, removeEvent: function (type, handler) { if (handlers[type] instanceof Array) { muphy.each(this.handlers[type], function (i) { if (this === handlers) { this.handlers[type].splice(i, 1); return false; } }); } }, fire: function (event) { if (!event.target) { event.target = this; } if (this.handlers[event.type] instanceof Array) { muphy.each(this.handlers[event.type], function () { this(event); }) } } } })(muphy); window.$m = muphy; })(window, jQuery);