现在的位置: 首页 > easyui > Base > parser > 正文
jQuery Easyui 源码分析之parser组件
2012年12月03日 parser, 源码分析 ⁄ 共 6437字 评论数 5 ⁄ 被围观 9,936 views+

parser组件作为easyui的基础类组件,其实担当者相当重要的角色,我们之所以能够通过定义一些样式就能完成对页面的自动渲染,完全是依靠parser组件;同时parser组件内部还定义了公用的属性转化器等几个实用工具,话不多说了,直接上带有注释的代码:

  1. /**  
  2.  * jQuery EasyUI 1.3.1  
  3.  * Licensed under the GPL terms  
  4.  * To use it on other terms please contact us  
  5.  * Copyright(c) 2009-2012 stworthy [ stworthy@gmail.com ]  
  6.  * (function($){})(jQuery) 定义一个匿名函数,并将jQuery对象作为实参传给这个匿名函数运行之。  
  7.  *   
  8.  */  
  9. (function($){   
  10.     //在jQuery对象定义全局属性parser,parser属性也是对象,其自身又包含:auto,onComplete,plugins,parse,parseOptions这几个属性。   
  11.     $.parser = {   
  12.         //设置是否自动渲染页面(或者为DOM块)的开关   
  13.         auto: true,   
  14.         //渲染完成后会触发onComplete事件(如果该事件绑定了处理函数,则每次调用parser渲染DOM后都会触发一次该事件绑定的处理函数)   
  15.         onComplete: function(_1){   
  16.         },   
  17.         //plugins属性枚举出了所有组件名称标识。   
  18.         plugins: ["draggable""droppable""resizable""pagination""linkbutton""menu""menubutton""splitbutton""progressbar""tree""combobox""combotree""combogrid""numberbox""validatebox""searchbox""numberspinner""timespinner""calendar""datebox""datetimebox""slider""layout""panel""datagrid""propertygrid""treegrid""tabs""accordion""window""dialog"],   
  19.         //parse就是实现渲染DOM的核心方法了,入参为DOM对象,其实也就是某个DOM块,不传入参的话,则是对整个页面进行渲染。   
  20.         parse: function(_2){   
  21.             var aa = [];   
  22.             for (var i = 0; i < $.parser.plugins.length; i++) {   
  23.                 var _3 = $.parser.plugins[i];   
  24.                 //查找指定DOM下的特定的easyui组件,即以_2为上下文查找_3组件对应的DOM对象,_2为空的话,则在整个document为上下文。   
  25.                 var r = $(".easyui-" + _3, _2);   
  26.                 if (r.length) {   
  27.                     if (r[_3]) {   
  28.                         //调用plugins某个里_3组件对象的构造函数,上下文当然也就是r对象自身了,也就是构造函数里面使用的this   
  29.                         //这个地方不要犯晕,r[_3]其实是function类型,其实也就是各个组件对应的构造函数。   
  30.                         //例如panel组件的代码里总有这样的定义:$.fn.panel = function(jq, options){...},这个匿名函数我就称之为组件的构造函数(这个称呼只是个约定)。   
  31.                         //而jQuery扩展fn的话等于扩展了全局方法到jQuery对象上,也就是所有的jQuery对象都具备了panel这个方法,   
  32.                         //如果没有使用easyloader的话,r对应其实已经具备了easyui所有组件的构造函数。   
  33.                         //这个地方如果不理解的话,请去翻阅jQuery的对象模型以及继承关系方面的资料。   
  34.                         r[_3]();   
  35.                     }   
  36.                     else {//这个else分支也只有在使用easyloader的时候才会调用到了   
  37.                         aa.push({   
  38.                             name: _3,   
  39.                             jq: r   
  40.                         });   
  41.                     }   
  42.                 }   
  43.             }   
  44.             if (aa.length && window.easyloader) {   
  45.                 var _4 = [];   
  46.                 for (var i = 0; i < aa.length; i++) {   
  47.                     _4.push(aa[i].name);   
  48.                 }   
  49.                 easyloader.load(_4, function(){   
  50.                     for (var i = 0; i < aa.length; i++) {   
  51.                         var _5 = aa[i].name;   
  52.                         var jq = aa[i].jq;   
  53.                         //调用组件的构造函数   
  54.                         jq[_5]();   
  55.                     }   
  56.                     $.parser.onComplete.call($.parser, _2);   
  57.                 });   
  58.             }   
  59.             else {   
  60.                 //这地方调用绑定的onComplete事件,入参为_2这个上下文。   
  61.                 //为什么这个写法?还不是想把_2作为参数传给onComplete事件绑定的函数处理程序嘛。   
  62.                 $.parser.onComplete.call($.parser, _2);   
  63.             }   
  64.         },   
  65.         //公用的属性转换器,兼容data-options方式和老方式,功能可谓灵活而强大。   
  66.         parseOptions: function(_6, _7){   
  67.             var t = $(_6);   
  68.             var _8 = {};   
  69.             var s = $.trim(t.attr("data-options"));   
  70.             if (s) {   
  71.                 var _9 = s.substring(0, 1);   
  72.                 var _a = s.substring(s.length - 1, 1);   
  73.                 if (_9 != "{") {   
  74.                     s = "{" + s;   
  75.                 }   
  76.                 if (_a != "}") {   
  77.                     s = s + "}";   
  78.                 }   
  79.                 _8 = (new Function("return " + s))();   
  80.             }   
  81.             if (_7) {   
  82.                 var _b = {};   
  83.                 for (var i = 0; i < _7.length; i++) {   
  84.                     var pp = _7[i];   
  85.                     if (typeof pp == "string") {   
  86.                         if (pp == "width" || pp == "height" || pp == "left" || pp == "top") {   
  87.                             _b[pp] = parseInt(_6.style[pp]) || undefined;   
  88.                         }   
  89.                         else {   
  90.                             _b[pp] = t.attr(pp);   
  91.                         }   
  92.                     }   
  93.                     else {   
  94.                         for (var _c in pp) {   
  95.                             var _d = pp[_c];   
  96.                             if (_d == "boolean") {   
  97.                                 _b[_c] = t.attr(_c) ? (t.attr(_c) == "true") : undefined;   
  98.                             }   
  99.                             else {   
  100.                                 if (_d == "number") {   
  101.                                     _b[_c] = t.attr(_c) == "0" ? 0 : parseFloat(t.attr(_c)) || undefined;   
  102.                                 }   
  103.                             }   
  104.                         }   
  105.                     }   
  106.                 }   
  107.                 $.extend(_8, _b);   
  108.             }   
  109.             return _8;   
  110.         }   
  111.     };   
  112.     //文档准备好后,根据$.parser.auto的设置来决定是否自动渲染   
  113.     $(function(){   
  114.         if (!window.easyloader && $.parser.auto) {   
  115.             $.parser.parse();   
  116.         }   
  117.     });   
  118.     //扩展_outerWidth方法到jQuery对象上,用于兼容IE这种不是正规盒子模型的另类浏览器   
  119.     $.fn._outerWidth = function(_e){   
  120.         if (_e == undefined) {   
  121.             if (this[0] == window) {   
  122.                 return this.width() || document.body.clientWidth;   
  123.             }   
  124.             return this.outerWidth() || 0;   
  125.         }   
  126.         return this.each(function(){   
  127.             if (!$.support.boxModel && $.browser.msie) {   
  128.                 $(this).width(_e);   
  129.             }   
  130.             else {   
  131.                 $(this).width(_e - ($(this).outerWidth() - $(this).width()));   
  132.             }   
  133.         });   
  134.     };   
  135.     //扩展_outerHeight方法到jQuery对象上,用于兼容IE这种不是正规盒子模型的另类浏览器   
  136.     $.fn._outerHeight = function(_f){   
  137.         if (_f == undefined) {   
  138.             if (this[0] == window) {   
  139.                 return this.height() || document.body.clientHeight;   
  140.             }   
  141.             return this.outerHeight() || 0;   
  142.         }   
  143.         return this.each(function(){   
  144.             if (!$.support.boxModel && $.browser.msie) {   
  145.                 $(this).height(_f);   
  146.             }   
  147.             else {   
  148.                 $(this).height(_f - ($(this).outerHeight() - $(this).height()));   
  149.             }   
  150.         });   
  151.     };   
  152.     //这句代码究竟有什么用途,请同学们在学习具体组件的源码时,自己体会吧。   
  153.     $.fn._propAttr = $.fn.prop || $.fn.attr;   
  154. })(jQuery);  

目前有 5 条留言 其中:访客:3 条, 博主:2 条

  1. peislin : 2012年12月03日17:13:00  -49楼 @回复 回复

    写的很详细啊……期待博主再接再厉,写出更多高质量的博文!

  2. 和尚 : 2014年06月27日16:09:56  -48楼 @回复 回复

    博主加油!!!!!!!写的很详细。大爱

给我留言

留言无头像?


×