這次帶給大家JavaScript的事件管理,使用JavaScript的事件管理的注意事項有哪些,下面就是實戰案例,一起來看一下。
在設計JavaScript xxsdk的時候考慮到能讓呼叫者參與到工作流程中來,開始用了回呼函數。如下:
this.foo = function(args,callbackFn) { //do something //then if callbackFn is a function callbackFn(); };
或在初始化的傳入config。
function SDK(config) { var configs = { onInit: function() { }, onFoo: function () { }, // on.... }; //合并参数 configs = $.extend(configs, config); this.foo = function (args) { //do something configs.onFoo(); }; }
但問題來了,隨著函數越多,第一種方式就顯得很煩,每個方法的參數後面要跟一個或多個回調函數,程式碼顯得不乾淨,而且只有用戶呼叫的時候才會執行回調,對於沒有暴露給使用者的方法就用不上。第二種方式,函數越多,config越長,建構程式碼顯得難看,另一方面就是一個方法只會觸發一個回呼。最後使用了下面的方式
先定義一個事件管理器,主要想法是讓每個事件類型對應一個回調列表,這樣可以讓外部對同一個事件關聯多次。取消某個關聯就是在該事件類型的函數清單中移除某個回呼函數。觸發就是把列表中函數全部執行一遍。當然還帶了參數。
var eventManger = { handlers: {}, //类型,绑定事件 addHandler:function(type,handler) { if (typeof this.handlers[type] == "undefined") { this.handlers[type] = [];//每个事件都可以绑定多次 } this.handlers[type].push(handler); }, removeHandler:function(type, handler) { var events = this.handlers[type]; for (var i = 0, len = events.length; i < len; i++) { if (events[i] == handler) { events.splice(i, 1); break; } } }, trigger: function (type) { if (this.handlers[type] instanceof Array) { var handlers = this.handlers[type]; var args = Array.prototype.slice.call(arguments, 1); for (var i = 0, len = handlers.length; i < len; i++) { handlers[i].apply(null, args); } } } };
然後在sdk中公佈關聯和移除的方法:
//给外部绑定事件 this.on = function(type, event) { eventManger.addHandler(type,event); }; //移除事件 this.off = function(type, event) { eventManger.removeHandler(type, event); };
在執行的過程中分別觸發事件:
this.init = function() { //do init eventManger.trigger('init'); }; this.start = function() { //do start eventManger.trigger('start'); }; this.connect = function() { eventManger.trigger('connect'); }; this.messages = function() { var msgs = []; msgs.push("你好吗"); msgs.push("我很好"); eventManger.trigger('messages',msgs); }; this.disconnect = function() { eventManger.trigger('disconnect'); };
那用戶在使用的時候就比較方便了。
//绑定connect sdk.on('connect', function () { console.log('connect'); });//绑定messages sdk.on('messages', function (data) { if (!data) return; if (data instanceof Array) { for (var i = 0; i < data.length; i++) { console.log(data[i]); } } else { console.log(data); } });
還可以先綁定,移除再綁定。
var oninit = function() { console.log('init...'); }; sdk.on('init', oninit); sdk.on('init', function () { console.log('other init'); }); sdk.off('init', oninit); sdk.init();
全部程式碼:
function SDK() { var eventManger = { handlers: {}, //类型,绑定事件 addHandler:function(type,handler) { if (typeof this.handlers[type] == "undefined") { this.handlers[type] = [];//每个事件都可以绑定多次 } this.handlers[type].push(handler); }, removeHandler:function(type, handler) { var events = this.handlers[type]; for (var i = 0, len = events.length; i < len; i++) { if (events[i] == handler) { events.splice(i, 1); break; } } }, trigger: function (type) { if (this.handlers[type] instanceof Array) { var handlers = this.handlers[type]; var args = Array.prototype.slice.call(arguments, 1); for (var i = 0, len = handlers.length; i < len; i++) { handlers[i].apply(null, args); } } } }; //给外部绑定事件 this.on = function(type, event) { eventManger.addHandler(type,event); }; //移除事件 this.off = function(type, event) { eventManger.removeHandler(type, event); }; this.init = function() { //do init eventManger.trigger('init'); }; this.start = function() { //do start eventManger.trigger('start'); }; this.connect = function() { eventManger.trigger('connect'); }; this.messages = function() { var msgs = []; msgs.push("你好吗"); msgs.push("我很好"); eventManger.trigger('messages',msgs); }; this.disconnect = function() { eventManger.trigger('disconnect'); }; this.autoRun = function() { this.init(); this.start(); this.connect(); this.messages(); this.disconnect(); }; } var sdk = new SDK(); var oninit = function() { console.log('init...'); }; sdk.on('init', oninit); sdk.on('start', function () { console.log('start'); }); sdk.on('connect', function () { console.log('connect'); }); sdk.on('messages', function (data) { if (!data) return; if (data instanceof Array) { for (var i = 0; i < data.length; i++) { console.log(data[i]); } } else { console.log(data); } }); sdk.on('disconnect', function () { console.log('disconnect'); }); sdk.autoRun(); sdk.on('init', function () { console.log('other init'); }); sdk.off('init', oninit); sdk.init();
View Code
執行結果:
也可以擴充一些方法once( ) 、removeListener() 、removeAllListeners()֖等
小結:事件的處理方式更簡潔且更有擴展性。 jquery的事件機制沒有將事件監聽函數綁定到DOM元素上,而是基於資料快取模組來管理的。這裡借鑒了下,對同一事件類型type的所有監聽物件handleObj構成監聽物件陣列handles。因為沒有牽涉到dom操作,所以相對也簡單些。
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
jQuery、Angular、node中的Promise詳解
以上是JavaScript的事件管理的詳細內容。更多資訊請關注PHP中文網其他相關文章!