zoukankan      html  css  js  c++  java
  • js设计模式方法的链式调用及回调

    // 方法的链式调用

    /*
     链式调用其实只不过是一种语法招数。它能让你通过重用一个初始操作来达到少量代码表达复杂操作的目的。这种技术包含两个部分:一个创建代表HTML元素的对象的工厂,以及一批对这个HTML元素执行某些操作的方法。每一个这种方法都可以在方法名前附上一个圆点后加入调用链中。方法的链式调用可以被视为选择网页上的一个元素对其进行一个或多个操作的过程。
     */
    // without chaining
    addEvent($('example'), 'click', function () {
        setStyle(this, 'color', 'green');
        show(this);
    });
    // with chaining
    $('example').addEvent('click', function () {
        $(this).setStyle('color', 'green').show();
    });
     
    // 调用链的结构
    /*
     把DOM集合的函数改造为一个构造器,把那些元素作为数组保存在一个实例属性中,并让所有定义在构造器函数的prototype属性所指对象中的方法都返回用以调用方法的那个实例的引用,那么它就具有了进行链式调用的能力。
     先把$函数该为一个工厂方法,它负责创建支持链式调用的对象。
     */
    (function () {
        // use a provate class
        function _$(els) {
            this.elements = [];
            for (var i = 0, len = els.length; i < len; i++) {
                var element = els[i];
                if (typeof element === 'string') {
                    element = document.getElementById(element);
                }
                this.elements.push(element);
            }
        }
     
        _$.prototype = {
            each: function (fn) {
                for (var i = 0, len = this.elements.length; i < len; i++) {
                    fn.call(this, this.elements[i]);
                }
                return this;
            },
            setStyle: function (prop, val) {
                this.each(function (el) {
                    if (typeof prop === 'object') {
                        for (var i in prop) {
                            if (!prop.hasOwnProperty(i)) {
                                continue;
                            }
                            el.style[i] = prop[i];
                        }
                    } else {
                        el.style[prop] = val;
                    }
                });
                return this;
            },
            show: function () {
                var that = this;
                this.each(function () {
                    that.setStyle('display', 'block');
                });
                return this;
            },
            addEvent: function (type, fn) {
                var add = function (el) {
                    if (window.addEventListener) {
                        el.addEventListener(type, fn, false);
                    } else if (window.attachEvent) {
                        el["e" + type + fn] = fn;
                        //把事件函数赋给自定义对象属性
                        el[type + fn] = function () {
                            el["e" + type + fn](window.event);
                        };
                        el.attachEvent("on" + type, el[type + fn]);
                    }
                };
                this.each(function (el) {
                    add(el);
                });
                return this;
            }
        };
     
        // the public interface remains the same
        window.$ = function () {
            return new _$(arguments);
        };
    })();
     
    $(window).addEvent('load', function () {
        $('test-1', 'test-2').show()
                .setStyle('color', 'red')
                .addEvent('click', function (e) {
                    $(this).setStyle({
                        backgroundColor: 'red',
                        color: 'green',
                        boxShadow: '0 0 20px rgba(0,0,0,0.5)'
                    });
                });
    });
     
     
    /*----------------------
     设计一个支持方法链式调用的js库
     --------------------*/
    // include syntactic sugar to help the development of our interface.
    Function.prototype.method = function (name, fn) {
        this.prototype[name] = fn;
        return this;
    };
    (function () {
        function _$(els) {
            this.elements = [];
            for (var i = 0; i < els.length; i++) {
                var element = els[i];
                if (typeof element === 'string') {
                    element = document.getElementById(element);
                }
                this.elements.push(element);
            }
            return this.elements;
        }
     
        /*
         Events
         * addEvent
         * getEvent
         */
        _$.method('addEvent', function (type, fn) {
            //...
     
        })
                .method('getEvent', function (e) {
                    //...
                })
            /*
             DOM
             * addClass
             * removeClass
             * replaceClass
             * hasClass
             * getStyle
             * setStyle
             */
                .method('addClass', function (className) {
                    //...
                })
                .method('removeClass', function (className) {
                    //...
                })
                .method('replaceClass', function (oldClass, newClass) {
                    //...
                })
                .method('hasClass', function (className) {
                    //...
                })
                .method('getStyle', function (prop) {
                    //...
                })
                .method('setStyle', function (prop, val) {
                    //...
                })
            /*
             AJAX
             * load,Fetches anHTML fragment from a URL and inserts it into an element
             */
                .method('load', function (url, method) {
                    //...
                });
     
        window.$ = function () {
            return new _$(arguments);
        };
    })();
     
    /*
     如果某个现有的API已经定义了一个$函数,那么我们的这个库会将其改写,更好地解决方案是添加一个安装器
     */
    Function.prototype.method = function (name, fn) {
        //...
    };
    (function () {
        function _$(els) {
            //...
        }
     
        _$.method('addEvent', function (type, fn) {
            //...
        });
     
        /*--------------------------------*/
        window.installHelper = function (scope, interface) {
            scope[interface] = function () {
                return new _$(arguments);
            };
        };
        /*--------------------------------*/
    })();
     
    // 使用
    installHelper(window, '$');
    $('example').show();
     
    // 更复杂的例子,添加到一个事先定义好的命名空间中
    // Define a namespace without overwriting it if it already exists
    window.com = window.com || {};
    com.example = com.example || {};
    com.example.util = com.example.util || {};
     
    installHelper(com.example.util, 'get');
     
    (function () {
        var get = com.example.util.get;
        get('example').addEvent('click', function (e) {
            get(this).addClass('hello');
        })
    })();
     
    // 使用回调从支持链式调用的方法获取数据
    /*
     对于取值器方法,你可能会希望它们返回你要的数据而不是返回this。不过,如果你把链式调用作为首要目标,希望所有方法的使用方式保持一致的话,那么你可以利用回调技术来返回所要的数据。
     */
    // API1类使用了普通的取值器(它中断了调用链)
    // API2类则使用了回调方法
    window.API = window.API || function () {
        var name = 'hellow world';
        // privileged mutator method
        this.setName = function (newName) {
            name = newName;
            return this;
        };
        // privileged accessor method
        this.getName = function () {
            return name;
        };
    };
     
    // implementation code
    var o = new API;
    console.log(o.getName());   // hellow world
    console.log(o.setName('Meow').getName());   //Meow
     
     
    // acessor with function callbacks
    window.API2 = window.API2 || function () {
        var name = 'hello world';
        this.setName = function (newName) {
            name = newName;
            return this;
        };
        this.getName = function (callback) {
            callback.call(this, name);
            return this;
        };
    };
     
    // implementation code
    var o2 = new API2;
    o2.getName(console.log).setName('Meow').getName(console.log);
  • 相关阅读:
    优酷土豆的Redis服务平台化之路
    [C#]使用Gembox.SpreadSheet向Excel写入数据及图表
    [C#]使用Join与GroupJoin将两个集合进行关联与分组
    [C#]使用TcpListener及TcpClient开发一个简单的Chat工具
    超棒黑客必备清单
    [C#]使用dnSpy对目标程序(EXE或DLL)进行反编译修改并编译运行
    [C#源代码]使用SCPI指令对通信端口(RS232/USB/GPIB/LAN)进行仪器编程
    [C#]使用Costura.Fody将源DLL合并到目标EXE
    [C#]使用ILMerge将源DLL合并到目标EXE(.NET4.6.2)
    详解C#7.0新特性
  • 原文地址:https://www.cnblogs.com/webFrontDev/p/2820384.html
Copyright © 2011-2022 走看看