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 相关文章推荐
表单的一些基本用法与技巧
Jul 15 Javascript
js 限制数字 js限制输入实现代码
Dec 04 Javascript
Jjcarousellite 实现图片列表滚动的简单实例
Nov 29 Javascript
Jquery ajaxStart()与ajaxStop()方法(实例讲解)
Dec 18 Javascript
jquery序列化表单以及回调函数的使用示例
Jul 02 Javascript
js实现文字超出部分用省略号代替实例代码
Sep 01 Javascript
利用BootStrap的Carousel.js实现轮播图动画效果
Dec 21 Javascript
js oncontextmenu事件使用详解
Mar 25 Javascript
jQuery图片查看插件Magnify开发详解
Dec 25 jQuery
JS/jQuery实现简单的开关灯效果【案例】
Feb 19 jQuery
webpack 动态批量加载文件的实现方法
Mar 19 Javascript
js实现Element中input组件的部分功能并封装成组件(实例代码)
Mar 02 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
利用谷歌 Translate API制作自己的翻译脚本
2014/06/04 PHP
Yii2下session跨域名共存的解决方案
2017/02/04 PHP
laravel中的一些简单实用功能
2018/11/03 PHP
jQuery 常见操作实现方式和常用函数方法总结
2011/05/06 Javascript
打开新窗口关闭当前页面不弹出关闭提示js代码
2013/03/18 Javascript
Javascript 中 null、NaN和undefined的区别总结
2013/04/10 Javascript
使用简洁的jQuery方法实现隔行换色功能
2014/01/02 Javascript
jquery中map函数与each函数的区别实例介绍
2014/06/23 Javascript
jquery.ajax之beforeSend方法使用介绍
2014/12/08 Javascript
jquery实现图片左右切换的方法
2015/05/07 Javascript
javascript实现状态栏文字首尾相接循环滚动的方法
2015/07/22 Javascript
JavaScript中的return语句简单介绍
2015/12/07 Javascript
探究JavaScript函数式编程的乐趣
2015/12/14 Javascript
jquery trigger实现联动的方法
2016/02/29 Javascript
Angular.js回顾ng-app和ng-model使用技巧
2016/04/26 Javascript
javascript 用函数实现继承详解
2016/05/28 Javascript
购物车前端开发(jQuery和bootstrap3)
2016/08/27 Javascript
python显示天气预报
2014/03/02 Python
使用python实现扫描端口示例
2014/03/29 Python
opencv转换颜色空间更改图片背景
2019/08/20 Python
python常见字符串处理函数与用法汇总
2019/10/30 Python
使用HTML5 Canvas API中的clip()方法裁剪区域图像
2016/03/25 HTML / CSS
HTML5实现锚点时请使用id取代name
2013/09/06 HTML / CSS
英国手工布艺沙发在线购买:Sofas & Stuff
2018/03/02 全球购物
意大利珠宝店:Luxury Zone
2019/01/05 全球购物
俄罗斯美容和健康网上商店:Созвездие Красоты
2019/07/23 全球购物
英国折扣高尔夫商店:Discount Golf Store
2019/11/19 全球购物
个性大学生自我评价
2013/12/04 职场文书
文秘专业个人求职信
2013/12/22 职场文书
报效祖国演讲稿
2014/09/15 职场文书
JS Object构造函数之Object.freeze
2021/04/28 Javascript
JS如何实现基于websocket的多端桥接平台
2021/05/14 Javascript
Java比较两个对象中全部属性值是否相等的方法
2021/08/07 Java/Android
python周期任务调度工具Schedule使用详解
2021/11/23 Python
angular异步验证器防抖实例详解
2022/03/31 Javascript
如何使用python包中的sched事件调度器
2022/04/30 Python