zoukankan      html  css  js  c++  java
  • get first、set all策略QWrap的FunctionH.mul变换 之一

    get first、set all策略------QWrap的Function.mul变换 之一

    get first/set all策略由jquery推出以来,很深入人心,很多享受他便利的使用者,甚至都没意识到还有这个策略的存在----大道自然啊。
    它是个什么样的策略呢?

    代码1(代码仅为示意,不是可执行的):
    W([el1,el2]).setValue(1),
    很显然,这句话会造成el1.value=1,el2.value=1。
    即,操作对所有元素都有效。
    对于set操作,各个框架都是一样的策略:set all。

    代码2:
    W([el1,el2]).getValue() 返回的是什么呢?
    A: 是el1.value
    B: 还是[el1.value,el2.value] ?
    这两个结果,A代表的是get first;B代表的是get all。
    Jquery选择了A策略,即get first,这样看起来更贴近用户的需求。
    而YUI3的NodeList选用了B策略,即get all,或许他认为这样看起来语义更严谨,也或许他在实现上有顾虑。

    QWrap可以无所顾虑的来决定:默认是get first策略,也可以配置成get all策略。
    这是因为QWrap的思路就是:“代码”与“使用”相分离。
    即,代码是一样的,但使用的是经过变换后的接口或方法。

    get first、set all策略,主要通过FunctionH.mul变换来实现。
    看一下mul是个什么样的方法:

    代码
    /** 对函数进行集化,使其第一个参数可以处理数组
    * @method mul
    * @static
    * @param {function} func
    * @param {boolean} recursive 是否递归
    * @param {boolean} getFirst 是否只是getFirst
    * @return {Object} 已集化的函数
    */
    function mul(func, getFirst){
    //get First
    if(getFirst){
    //以下代码,递归回溯寻找第一个有效元素,例如[[[],[]],[[],[el]]] 会找到el,再去执行func
    //注意:诸如[null]、[undefined]这种会被当做非有效元素而忽略
    function findFirst(list){
    if(!(list instanceof Array)) {
    return list;
    }
    for(var i=0;i<list.length;i++){
    var firstOne = findFirst(list[i]);
    if(null != firstOne) return firstOne;
    }
    };

    return function(){
    var firstOne = findFirst(arguments[0]);
    if(firstOne){
    var args = [].slice.call(arguments,0);
    args[
    0] = firstOne;
    return func.apply(this,args);
    }
    };
    }

    //get All
    var newFunc = function(){
    var list = arguments[0];
    if(list instanceof Array){
    var ret = [];
    var moreArgs = [].slice.call(arguments,0);
    for(var i = 0, len = list.length; i < len; i++){
    moreArgs[
    0]=list[i];
    var r = newFunc.apply(this, moreArgs);
    ret.push(r);
    }
    return ret;
    }
    else{
    return func.apply(this, arguments);
    }
    }
    return newFunc;
    };



    mul是multiple的缩写,它的作用是让一个函数的第一个参数可以是数组。
    原生的getValue/setValue方法不必关心第一个参数是数组的情况。
    如以下的NodeH。(H是Helper的缩写,Helper规范约定其所有方法都是静态方法,并且第一个参数有同样的针对性。参见QWrap的Helper规范)

    代码
    var NodeH={
    getValue:
    function(el){
    return el.value;
    },
    setValue:
    function(el,value){
    el.value
    =value;
    },
    getStyle:
    function(el,prop){
    return el.style[prop];
    },
    setStyle:
    function(el,prop,value){
    el.style[prop]
    =value;
    }
    };



    这里,我们需要一个NodeW的对象,(W是Wrap的缩写,为了保护core的核心,而在外面加一层Wrap,详细参见QWrap设计篇之Wrap。jquery、YUI.NodeList、YUI.Node都可以理解成一个Wrap)

    function NodeW(core){
    this.core=core;
    };



    以下变换需要用到另一个变换:methodize:

    function methodize(func,chain){
    return function(){
    var ret = func.apply(null,[this.core].concat([].slice.call(arguments)));
    return chain?this:ret;
    }
    };



    好了,以下几句话就可以做到NodeW用起来就像是一个jquery对象了

    代码
    NodeW.prototype.getValue=methodize(mul(NodeH.getValue,true));
    NodeW.prototype.getStyle
    =methodize(mul(NodeH.getStyle,true));
    NodeW.prototype.setValue
    =methodize(mul(NodeH.setValue),true);
    NodeW.prototype.setStyle
    =methodize(mul(NodeH.setStyle),true);



    之后,我们就可以像jquery一样来这样的调用了。

    var els=document.getElementsByTagName('input');
    var w=new NodeW([els[0],els[1]]);
    var val=w.setStyle('color','red').setValue(1).getValue();
    alert(val);



    全部代码如下:

    代码
    <HTML><HEAD><TITLE>QWrap---FunctionH.mul</TITLE>
    <META content="text/html; charset=gb2312" http-equiv=Content-Type>
    </HEAD>
    <BODY>
    <input id="test1">
    <input id="test2">
    <input type=button value="运行test" onclick="test();">
    </BODY>
    <script>
    /** 对函数进行集化,使其第一个参数可以处理数组
    * @method mul
    * @static
    * @param {function} func
    * @param {boolean} recursive 是否递归
    * @param {boolean} getFirst 是否只是getFirst
    * @return {Object} 已集化的函数
    */
    function mul(func, getFirst){
    //get First
    if(getFirst){
    //以下代码,递归回溯寻找第一个有效元素,例如[[[],[]],[[],[el]]] 会找到el,再去执行func
    //注意:诸如[null]、[undefined]这种会被当做非有效元素而忽略
    function findFirst(list){
    if(!(list instanceof Array)) {
    return list;
    }
    for(var i=0;i<list.length;i++){
    var firstOne = findFirst(list[i]);
    if(null != firstOne) return firstOne;
    }
    };

    return function(){
    var firstOne = findFirst(arguments[0]);
    if(firstOne){
    var args = [].slice.call(arguments,0);
    args[
    0] = firstOne;
    return func.apply(this,args);
    }
    };
    }

    //get All
    var newFunc = function(){
    var list = arguments[0];
    if(list instanceof Array){
    var ret = [];
    var moreArgs = [].slice.call(arguments,0);
    for(var i = 0, len = list.length; i < len; i++){
    moreArgs[
    0]=list[i];
    var r = newFunc.apply(this, moreArgs);
    ret.push(r);
    }
    return ret;
    }
    else{
    return func.apply(this, arguments);
    }
    }
    return newFunc;
    };

    function methodize(func,chain){
    return function(){
    var ret = func.apply(null,[this.core].concat([].slice.call(arguments)));
    return chain?this:ret;
    }
    };

    var NodeH={
    getValue:
    function(el){
    return el.value;
    },
    setValue:
    function(el,value){
    el.value
    =value;
    },
    getStyle:
    function(el,prop){
    return el.style[prop];
    },
    setStyle:
    function(el,prop,value){
    el.style[prop]
    =value;
    }
    };

    function NodeW(core){
    this.core=core;
    };

    NodeW.prototype.getValue
    =methodize(mul(NodeH.getValue,true));
    NodeW.prototype.getStyle
    =methodize(mul(NodeH.getStyle,true));
    NodeW.prototype.setValue
    =methodize(mul(NodeH.setValue),true);
    NodeW.prototype.setStyle
    =methodize(mul(NodeH.setStyle),true);

    function test(){
    var els=document.getElementsByTagName('input');
    var w=new NodeW([els[0],els[1]]);
    var val=w.setStyle('color','red').setValue(1).getValue();
    alert(val);
    }

    </script>


    </HTML>



    说明:
    mul还有其它参数、等等更多内容,可以参见QWrap的QW.FunctionH,相信对于JS开发者会有很多帮助。
    QWrap 参见:http://github.com/wedteam/qwrap
    另外,LC同学也写过一篇介绍QWrap骨骼的文章,参见:http://archive.cnblogs.com/a/1926941/
    月影也写过一篇:“浅说QWrap的核心机制”  http://bbs.51js.com/viewthread.php?tid=88347

  • 相关阅读:
    jQuery.ajax()方法笔记
    Docker安装
    Linux下Nginx+keepalived实现高可用
    Linux安装Nginx
    Redis主从、哨兵、Cluster特性
    Linux搭建redis集群
    Linux搭建redis单机
    HashMap知识总结(jdk1.8)
    如何避免form提交进行页面跳转
    异步上传文件,jquery+ajax,显示进度条
  • 原文地址:https://www.cnblogs.com/jkisjk/p/QWrap_Function_mul_01.html
Copyright © 2011-2022 走看看