zoukankan      html  css  js  c++  java
  • QWrap简介之:dom_retouch NodeW 勇士装甲

    在《QWrap简介之:NodeW ---Node包装
    一文中已介绍过NodeW,不过,那是他没配装备的样子。
    NodeW是一个勇士的坯子,需要装甲以后才能成为真正的勇士。
    QWrap已经有很多"甲",包括:NodeH、EventTargetH、JssTargetH、ArrayH。
    可以这么说:由Helper堆砌起来的QWrap只是一个工具集,与是YUI2类似。我们用工具也可以来做事,不过显得有些生硬。我们还可以请一个勇士来,让勇士来使用这些工具,而我们来指挥勇士。
    js/dom/dom_retouch.js的一个主要任务,就是为NodeW这个勇士装甲。

    好的,我们明白了这些,那我们就来看所推荐的core_retouch吧。其中与NodeW有关的一段如下
    NodeW.pluginHelper(NodeH, NodeC.wrapMethods, NodeC.gsetterMethods);
    NodeW.pluginHelper(EventTargetH,
    'operator');
    NodeW.pluginHelper(JssTargetH, NodeC.wrapMethods, {jss: [
    '', 'getJss', 'setJss']});

    var ah = QW.ObjectH.dump(QW.ArrayH, NodeC.arrayMethods);
    ah
    = methodize(ah);
    ah
    = rwrap(ah, NodeW, NodeC.wrapMethods);
    mix(NodeW.prototype, ah);


    前三句是为NodeW装备NodeH、EventTargetH、JssTargetH。
    后面几句是为NodeW装备ArrayH,使NodeW的ArrayLike的功能从ArrayH中获得。
    这里用到了两个之前没有介绍过的东西。NodeW.pluginHelper、NodeC。它们分别是什么?

    NodeW.pluginHelper是NodeW的一个静态方法,作用是“在NodeW中植入一个针对Node的Helper”,它的代码也很简单,如下:

    /**
    * 在NodeW中植入一个针对Node的Helper
    * @method pluginHelper
    * @static
    * @param {helper} helper 必须是一个针对Node(元素)的Helper
    * @param {string|json} wrapConfig wrap参数
    * @param {json} gsetterConfig (Optional) gsetter 参数
    * @return {NodeW}
    */

    NodeW.pluginHelper
    = function(helper, wrapConfig, gsetterConfig) {
    var HelperH = QW.HelperH;

    helper
    = HelperH.mul(helper, wrapConfig); //支持第一个参数为array

    var st = HelperH.rwrap(helper, NodeW, wrapConfig); //对返回值进行包装处理
    if (gsetterConfig) {//如果有gsetter,需要对表态方法gsetter化
    st = HelperH.gsetter(st, gsetterConfig);
    }

    mix(NodeW, st);
    //应用于NodeW的静态方法

    var pro = HelperH.methodize(helper, 'core');
    pro
    = HelperH.rwrap(pro, NodeW, wrapConfig);
    if (gsetterConfig) {
    pro
    = HelperH.gsetter(pro, gsetterConfig);
    }
    mix(NodeW.prototype, pro);
    };

    以下面的一个简单例子来说明它的功能:
    var myHelper={
    getValue:
    function(el){return el.value;},
    setValue:
    function(el,value){el.value=value;}
    };
    NodeW.pluginHelper(
    myHelper,
    {
    getValue:
    'getter_first_all',
    setValue:
    'operator'
    }, {
    val: [
    'getValue', 'setValue']
    }
    );

    它们产出的结果是:
    NodeW.prototype多出了以下系列方法:
    getValue,用法如:W('input').getValue(); //返回第一个input的value值
    getValueAll,用法如:W('input').getValueAll(); //返回所有input元素的值组成的组
    setValue,用法如:W('input').setValue(1); //所有input赋值成1
    val,是一个gsetter,即getter_first与setter的混合体,由参数个数决定是getter_first还是setter。用法如:
        W('input').val(); //返回第一个input的value值
        W('input').val(1); //所有input赋值成1
    当然,作为setter时,会返回本身,可以继续操作。例如:
    W('input').val(1).val();//先设value再获取第一个value
    除了上面的类似于jquery的用法外,还会产生静态用法。静态用法在某些时候会省写一个括号,例如,假设我们已以知道el=某INPUT原素,以下两行会有同样的功能:
    W.val(el);
    W(el).val();
    有的同学可能会认为用法太多让人烦恼,那可以忽略掉静态用法。

    以上,是否对NodeH.pluginHelper有了感性的认识?
    那我们再回顾一下pluginHelper做了哪些事:
    1 mul化:让myHelper里不支持参数为数组的getValue/setValue支持数组了。
    2 分静态和原型不同处理,其中
      静态渲染:先按配置决定是否包装与包装形式,再按配置让某些方法配对形成gsetter,再把这些静态函数渲染到NodeW上。
      原型渲染:先方法化,再按配置决定是否包装与包装形式,再按配置让某些方法配对形成gsetter,再把这些方法渲染到NodeW.prototype上。

    上面都讲到了NodeC配置,那再看一下js/dom/node.c.js
    View Code
    (function() {
    var queryer = 'queryer',
    operator
    = 'operator',
    getter_all
    = 'getter_all',
    getter_first
    = 'getter_first',
    getter_first_all
    = 'getter_first_all';

    QW.NodeC
    = {
    getterType: getter_first,
    arrayMethods:
    'map,forEach,toArray'.split(','),
    //部分Array的方法也会集成到NodeW里
    wrapMethods: {
    //queryer “返回值”的包装结果
    //operator 如果是静态方法,返回第一个参数的包装,如果是原型方法,返回本身
    //getter_all 如果是array,则每一个执行,并返回
    //getter_first 如果是array,则返回第一个执行的返回值
    //getter_first_all 同getter,产出两个方法,一个是getterFirst,一个是getterAll
    //NodeH系列
    g: queryer,
    one: queryer,
    query: queryer,
    getElementsByClass: queryer,
    outerHTML: getter_first,
    hasClass: getter_first,
    addClass: operator,
    removeClass: operator,
    replaceClass: operator,
    toggleClass: operator,
    show: operator,
    hide: operator,
    toggle: operator,
    isVisible: getter_first,
    getXY: getter_first_all,
    setXY: operator,
    setSize: operator,
    setInnerSize: operator,
    setRect: operator,
    setInnerRect: operator,
    getSize: getter_first_all,
    getRect: getter_first_all,
    nextSibling: queryer,
    previousSibling: queryer,
    ancestorNode: queryer,
    parentNode: queryer,
    firstChild: queryer,
    lastChild: queryer,
    contains: getter_first,
    insertAdjacentHTML: operator,
    insertAdjacentElement: operator,
    insert: operator,
    insertTo: operator,
    appendChild: operator,
    insertSiblingBefore: operator,
    insertSiblingAfter: operator,
    insertBefore: operator,
    insertAfter: operator,
    replaceNode: operator,
    replaceChild: operator,
    removeNode: operator,
    empty: operator,
    removeChild: operator,
    get: getter_first_all,
    set: operator,
    getAttr: getter_first_all,
    setAttr: operator,
    removeAttr: operator,
    getValue: getter_first_all,
    setValue: operator,
    getHtml: getter_first_all,
    setHtml: operator,
    encodeURIForm: getter_first,
    isFormChanged: getter_first,
    cloneNode: queryer,
    getStyle: getter_first_all,
    getCurrentStyle: getter_first_all,
    setStyle: operator,
    borderWidth: getter_first,
    paddingWidth: getter_first,
    marginWidth: getter_first,

    //TargetH系列
    //……
    //JssTargetH系列
    getOwnJss: getter_first_all,
    getJss: getter_first_all,
    setJss: operator,
    removeJss: operator,

    //ArrayH系列
    forEach: operator
    },
    gsetterMethods: {
    //在此json里的方法,会是一个getter与setter的混合体
    val: ['getValue', 'setValue'],
    html: [
    'getHtml', 'setHtml'],
    attr: [
    '', 'getAttr', 'setAttr'],
    css: [
    '', 'getCurrentStyle', 'setStyle'],
    size: [
    'getSize', 'setInnerSize'],
    xy: [
    'getXY', 'setXY']
    }
    };

    }());


    其中wrapMethods的配置规则为:
        //queryer “返回值”的包装结果
        //operator 如果是静态方法,返回第一个参数的包装,如果是原型方法,返回本身
        //getter_all 如果是array,则每一个执行,并返回
        //getter_first 如果是array,则返回第一个执行的返回值
        //getter_first_all 同getter,产出两个方法,一个是getterFirst,一个是getterAll
    除了getter_all在实际中没用到外,其它几个都有用到。
    上面的例如中,如果把getValue配置成getter_all,那么,W('input').getValue()将会返回所有input元素的值组成的数组。这个结果与YUI3中的NodeList的结果一致,与jquery的结果不一致。
    实际上,getValue配置的是get_first_all,所以,它会产出两个方法,即:
    W('input').getValue()//返回第一个input的value值
    W('input').getValueAll()//返回所有input元素的值组成的数组
    前者与jquery一致,后者与YUI3的NodeList一致。
    我们并没有改变NodeH的代码,而只是改变NodeC配置,就同时满足了jquery追求与yui3追求。
    这也正是qwrap的retouch机制的灵活性的体现:一份严谨生硬的工具集,经retouch,产出个性易用有灵性的产品。

    dom_retouch.js中除了为NodeW装甲之外,也产出一个新的QW.Dom的命名空间来,它把DomU、NodeH、EventTargetH、JssTargetH的静态方法集中到一起,这个与YUI2的Dom很相似,就是一个与Dom有关的静态方法集,可以满足YUI2习惯的用户。

    另外,还有dom_retouch.js中还有两段略有争议,近期会作出调整,可以忽略。


    附: QWrap网址:http://www.qwrap.com
  • 相关阅读:
    Java数据库操作学习
    c3p0配置
    CachedRowSet 接口
    Android Library的依赖方式及发布(转)
    网站测试
    MySQL Server逻辑架构
    Service生命周期
    Activity的生命周期
    Android应用框架中的四个核心要点
    Android 最新架构
  • 原文地址:https://www.cnblogs.com/jkisjk/p/qwrap_dom_retouch.html
Copyright © 2011-2022 走看看