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 相关文章推荐
破除网页鼠标右键被禁用的绝招大全
Dec 27 Javascript
JQuery Dialog(JS 模态窗口,可拖拽的DIV)
Feb 07 Javascript
js 自动播放的实例代码
Nov 19 Javascript
开发插件的两个方法jquery.fn.extend与jquery.extend
Nov 21 Javascript
使用javascript实现json数据以csv格式下载
Jan 09 Javascript
jQuery实现鼠标悬停背景翻转的黑色导航菜单代码
Sep 14 Javascript
基于JavaScript如何实现私有成员的语法特征及私有成员的实现方式
Oct 28 Javascript
设置cookie指定时间失效(实例代码)
May 28 Javascript
vue 登录滑动验证实现代码
Aug 24 Javascript
Vue.js 中的 v-cloak 指令及使用详解
Nov 19 Javascript
vue中子组件传递数据给父组件的讲解
Jan 27 Javascript
vue.js路由mode配置之去掉url上默认的#方法
Nov 01 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
《PHP边学边教》(02.Apache+PHP环境配置――上篇)
2006/12/13 PHP
php网站来路获取代码(针对搜索引擎)
2010/06/08 PHP
php获取参数的几种方法总结
2014/02/18 PHP
从PHP的源码中深入了解stdClass类
2014/04/18 PHP
php 实现Hash表功能实例详解
2016/11/29 PHP
php+webSoket实现聊天室示例代码(附源码)
2017/02/17 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
PHP通过curl获取接口URL的数据方法
2018/05/31 PHP
jQuery方法简洁实现隔行换色及toggleClass的使用
2013/03/15 Javascript
javascript验证邮件地址和MX记录的方法
2015/06/16 Javascript
一步步教大家编写酷炫的导航栏js+css实现
2016/03/14 Javascript
JavaScript实现点击按钮复制指定区域文本(推荐)
2016/11/25 Javascript
JavaScript中Array对象用法实例总结
2016/11/29 Javascript
客户端(vue框架)与服务器(koa框架)通信及服务器跨域配置详解
2017/08/26 Javascript
p5.js入门教程之图片加载
2018/03/20 Javascript
VUE实现可随意拖动的弹窗组件
2018/09/25 Javascript
JavaScript变速动画函数封装添加任意多个属性
2019/04/03 Javascript
使用next.js开发网址缩短服务的方法
2020/06/17 Javascript
查找Vue中下标的操作(some和findindex)
2020/08/12 Javascript
[46:47]2014 DOTA2国际邀请赛中国区预选赛5.21 LGD-CDEC VS NE
2014/05/22 DOTA
Python的自动化部署模块Fabric的安装及使用指南
2016/01/19 Python
解决TensorFlow模型恢复报错的问题
2020/02/06 Python
英国领先的奢侈品零售商之一:CRUISE
2016/12/02 全球购物
购买正版游戏和游戏激活码:Green Man Gaming
2019/11/06 全球购物
北京某公司的.net笔试题
2014/03/20 面试题
新闻专业推荐信范文
2013/11/20 职场文书
工商治理实习生的自我评价分享
2014/02/20 职场文书
《埃及的金字塔》教学反思
2014/04/07 职场文书
《生命 生命》教学反思
2014/04/19 职场文书
趣味运动会开幕词
2015/01/28 职场文书
客服专员岗位职责范本
2015/04/07 职场文书
2017元旦晚会开幕词
2016/03/03 职场文书
工作建议书范文
2019/07/08 职场文书
大学生创业计划书常用模板
2019/08/07 职场文书
超级详细实用的pycharm常用快捷键
2021/05/12 Python
关于Python使用turtle库画任意图的问题
2022/04/01 Python