JS链式调用的实现方法


Posted in Javascript onMarch 07, 2013

链式调用
    链式调用其实只不过是一种语法招数。它能让你通过重用一个初始操作来达到用少量代码表达复杂操作的目的。该技术包括两个部分:

一个创建代表HTML元素的对象的工厂。

一批对这个HTML元素执行某些操作的方法。

调用链的结构
$函数负责创建支持链式调用的对象

(function() {
    /*
     * 创建一个私有class
     * @param {Object} els  arguments 所有参数组成的类数组
     */
    function _$(els) {
        this.elements = [];             //存放HTML元素
        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);
        }
    }
    //对HTML元素可执行的操作
    _$.prototype = {
        each: function() {},
        setStyle: function() {},
        show: function() {},
        addEvent: function() {},
    };    
    //对外开放的接口
    window.$ = function() {
        return new _$(arguments);
    };   
})();

由于所有对象都会继承其原型对象的属性和方法,所以我们可以让定义在原型对象中的那些方法都返回用以调用方法的实例对象的引用,这样就可以对那些方法进行链式调用了。

(function() {
    /*
     * 创建一个私有class
     * @param {Object} els  arguments 所有参数组成的类数组
     */
    function _$(els) {
        //...
    }
    //对HTML元素可执行的操作
    _$.prototype = {
        each: function(fn) {        //fn 回调函数
            for(var i=0; i<this.elements.length; i++) {
                //执行len次,每次把一个元素elements[i]作为参数传递过去
                fn.call(this, this.elements[i]);
            }
            return this;
        },
        setStyle: function(prop, value) {
            this.each(function(el) {
                el.style[prop] = value;
            });
            return this;
        },
        show: function() {
            var that = this;
            this.each(function(el) {
                that.setStyle('display', 'block');
            });
            return this;
        },
        addEvent: function(type, fn) {
            var addHandle = function(el) {
                if(document.addEventListener) {
                    el.addEventListener(type, fn, false);
                }else if(document.attachEvent) {
                    el.attachEvent('on'+type, fn);
                }
            };
            this.each(function(el) {
                addHandle(el);
            });
            return this;  
        }
    };
    //对外开放的接口
    window.$ = function() {
        return new _$(arguments);
    }})();

//----------------------- test --------
$(window).addEvent('load', function() {
    $('test-1', 'test-2').show()
    .setStyle('color', 'red')
    .addEvent('click', function() {
        $(this).setStyle('color', 'green');
    });
})

链式调用的方法获取数据
    使用回调函数从支持链式调用的方法获取数据。链式调用很适合赋值器方法,但对于取值器方法,你可能希望他们返回你要的数据而不是this(调用该方法的对象).解决方案:利用回调技术返回所要的数据.

window.API = window.API || function() {
    var name = 'mackxu';
    //特权方法
    this.setName = function(name0) {
        name = name0;
        return this;
    };
    this.getName = function(callback) {
        callback.call(this, name);
        return this;
    };
};
//------------- test ---
var obj = new API();
obj.getName(console.log).setName('zhangsan').getName(console.log);

设计一个支持方法链式调用的JS库
JS库特征:

事件: 添加和删除事件监听器、对事件对象进行规划化处理

DOM: 类名管理、样式管理

Ajax: 对XMLHttpRequest进行规范化处理

Function.prototype.method = function(name, fn) {
    this.prototype[name] = fn;
    return this;
};
(function() {
    function _$(els) {
        //...
    }
    /*
     * Events
     *      addEvent
     *      removeEvent
     */
    _$.method('addEvent', function(type, fn) {
        //...  
    }).method('removeEvent', function(type, fn) {    })
    /*
     * DOM
     *      addClass
     *      removeClass
     *      hover
     *      hasClass
     *      getClass
     *      getStyle
     *      setStyle
     */
    .method('addClass', function(classname) {
        //...
    }).method('removeClass', function(classname) {
        //...
    }).method('hover', function(newclass, oldclass) {
        //...
    }).method('hasClass', function(classname) {
        //...
    }).method('getClass', function(classname) {
        //...
    }).method('getStyle', function(prop) {
        //...
    }).method('setStyle', function(prop, val) {
        //...
    })
    /*
     * AJAX
     *      ajax
     */
    .method('ajax', function(url, method) {
        //...
    });
    window.$ = function() {
        return new _$(arguments);
    };
    //解决JS库命名冲突问题
    window.installHelper = function(scope, interface) {
        scope[interface] = function() {
            return _$(arguments)
        }
    }  
})();

小结:

    链式调用有助于简化代码的编写工作,并在某种程度上可以让代码更加简洁、易读。很多时候使用链式调用可以避免多次重复使用一个对象变量,从而减少代码量。如果想让类的接口保持一致,让赋值器和取值器都支持链式调用,那么你可以在取值器中使用回调函数来解决获取数据问题。

Javascript 相关文章推荐
JQueryiframe页面操作父页面中的元素与方法(实例讲解)
Nov 19 Javascript
如何将网页表格内容导入excel
Feb 18 Javascript
简化版手机端照片预览组件
Apr 13 Javascript
javascript实现tab响应式切换特效
Jan 29 Javascript
tablesorter.js表格排序使用方法(支持中文排序)
Feb 10 Javascript
AngularJs实现聊天列表实时刷新功能
Jun 15 Javascript
angular中ui calendar的一些使用心得(推荐)
Nov 03 Javascript
JavaScript实现删除数组重复元素的5种常用高效算法总结
Jan 18 Javascript
详解vue的diff算法原理
May 20 Javascript
webpack4.0 入门实践教程
Oct 08 Javascript
小程序中this.setData的使用和注意事项
Aug 28 Javascript
Vue-Cli项目优化操作的实现
Oct 27 Javascript
jQuery滚动加载图片效果的实现
Mar 06 #Javascript
HTML上传控件取消选择
Mar 06 #Javascript
jQuery操作Select选择的Text和Value(获取/设置/添加/删除)
Mar 06 #Javascript
JQuery操作tr和td内容的方法实例
Mar 06 #Javascript
node在两个div之间移动,用ztree实现
Mar 06 #Javascript
js实现一个省市区三级联动选择框代码分享
Mar 06 #Javascript
自己写了一个展开和收起的多更能型的js效果
Mar 05 #Javascript
You might like
咖啡冲泡指南 咖啡有哪些制作方式 单品咖啡 意式咖啡
2021/03/06 冲泡冲煮
怎么样可以把 phpinfo()屏蔽掉?
2006/11/24 PHP
过滤掉PHP数组中的重复值的实现代码
2011/07/17 PHP
PHP新手NOTICE错误常见解决方法
2011/12/07 PHP
php smarty truncate UTF8乱码问题解决办法
2014/06/13 PHP
destoon数据库表说明汇总
2014/07/15 PHP
php将日期格式转换成xx天前的格式
2015/04/16 PHP
获取内联和链接中的样式(js代码)
2013/04/11 Javascript
如何让页面加载完成后执行js
2013/06/26 Javascript
通过js获取div的background-image属性
2013/10/15 Javascript
js 走马灯简单实例
2013/11/21 Javascript
js动态往表格的td中添加图片并注册事件
2014/06/12 Javascript
JS实现带提示的星级评分效果完整实例
2015/10/30 Javascript
js对象浅拷贝和深拷贝详解
2016/09/05 Javascript
vue 监听键盘回车事件详解 @keyup.enter || @keyup.enter.native
2018/08/25 Javascript
three.js搭建室内场景教程
2018/12/30 Javascript
基于vue-cli搭建多模块且各模块独立打包的项目
2019/06/12 Javascript
vue项目中定义全局变量、函数的几种方法
2019/11/08 Javascript
Vue-axios-post数据后端接不到问题解决
2020/01/09 Javascript
JavaScript使用prototype属性实现继承操作示例
2020/05/22 Javascript
python使用ctypes模块调用windowsapi获取系统版本示例
2014/04/17 Python
Python base64编码解码实例
2015/06/21 Python
python数据结构之图的实现方法
2015/07/08 Python
python+pillow绘制矩阵盖尔圆简单实例
2018/01/16 Python
Django中更改默认数据库为mysql的方法示例
2018/12/05 Python
python实现截取屏幕保存文件,删除N天前截图的例子
2019/08/27 Python
django 解决model中类写不到数据库中,数据库无此字段的问题
2020/05/20 Python
pandas数据处理之绘图的实现
2020/06/15 Python
关键字throw与throws的用法差异
2016/11/22 面试题
大学生文员专业个人求职信范文
2014/01/05 职场文书
青春励志演讲稿
2014/04/29 职场文书
领导班子作风建设剖析材料
2014/10/11 职场文书
2014年大学班长工作总结
2014/11/14 职场文书
幼儿园小班开学寄语
2015/05/27 职场文书
导游词之潮音寺
2019/09/26 职场文书
MySql存储过程之逻辑判断和条件控制
2021/05/26 MySQL