zoukankan      html  css  js  c++  java
  • 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操作,所以相对也简单些。

  • 相关阅读:
    [Unity3D]调用Android接口
    android studio build.gradle中 project.ANDROID_BUILD_SDK_VERSION
    java中static{}语句块详解
    [Android][Android Studio] *.jar 与 *.aar 的生成与*.aar导入项目方法
    c++中 extern
    android studio一直卡在Gradle:Executing tasks
    Android Studio导入第三方类库的方法
    Android按返回键退出程序但不销毁,程序后台运行,同QQ退出处理方式
    Ubuntu64位下使用eclipse闪退的解决
    Android4.1中BinderService的作用
  • 原文地址:https://www.cnblogs.com/stoneniqiu/p/5479246.html
Copyright © 2011-2022 走看看