Java程式員的JavaScript學習筆記(13—— jQuery UI),學習筆記jquery

來源:互聯網
上載者:User

Java程式員的JavaScript學習筆記(13—— jQuery UI),學習筆記jquery
計劃按如下順序完成這篇筆記:這是筆記的第13篇,今天我們聊聊jQuery EasyUI。EasyUI是jQuery的一個常用擴充,解決頁面組件的問題,實現了可拖拽組件、功能更豐富的下拉框、日期組件、表格組件等。今天我們嘗試,通過分析Easyui的模組化設計、介面風格、實現細節,來探索我們自己的jQuery擴充之道 和 頁面組件化之道。

作者部落格:http://blog.csdn.net/stationxp 作者微博:http://weibo.com/liuhailong2008  轉載請取得作者同意  

1 easyloader.jseasyloader是easyui的“載入器”,代碼分為四大部分:第1部分定義資源,代碼節選如下所示: 
var modules = {      progressbar:{           js:'jquery.progressbar.js',          css:'progressbar.css'      },      numberbox:{           js:'jquery.numberbox.js',           dependencies:['textbox']      },      parser:{           js:'jquery.parser.js'      } }; var locales = {  'zh_CN':'easyui-lang-zh_CN.js' };

作為一個可擴充外掛程式架構,同時考慮互連網頁對載入時間最佳化的需求,easyui提供了靈活的定製方式,而且解決了組件間依賴的問題。
第2部分定義載入方法這部分代碼冗長,除非想實現自己的web資源動態載入機制,否則粗粗過一遍,瞭解功能即可。定義的函數及調用關係如下所示。
 var queues = {}; function loadJs(url, callback){ } function runJs(url, callback){ loadJs(url, function(){}); } function loadCss(url, callback){} // 解決載入狀態的問題 loading/loaded function loadSingle(name, callback){ loadCss(url, function(){ }); loadJs(url, function(){ }); } //解決dependencies的問題 function loadModule(name, callback){loadSingle(m, function(){});}
這部分只是做了定義,並未調用。
第3部分是變數easyloader的定義代碼如下所示:
easyloader = {      modules:modules,      locales:locales,      base:'.',      theme:'default',      css:true,      locale:null,      timeout:2000,      load: function(name, callback){           loadCss(easyloader.base + name, callback);           loadJs(name, callback);           loadModule(name, callback);      },      onProgress: function(name){},      onLoad: function(name){} }; window.using = easyloader.load;

從代碼層面,只是定義了easyloader變數,並把load方法綁定到全域的using上去。如果使用者調用了 using('progressbar') 即可載入相應的模組。easyloader完整實現了作為loader的使命,它提供的只是一個代碼隔離機制和動態載入架構。
既然easyloader只是載入架構,那麼可easyui的具體組件之間,也就是若即若離的關係。我們完全可以繞開easyloader直接引用要使用的組件。是否真的可以這樣呢?看完第4部分再說。
第4部分是easyloader份外之事:parse代碼如下:
if (window.jQuery){      jQuery(function(){           easyloader.load('parser', function(){ // 即using                jQuery.parser.parse(); // 忽然意識到,easyloader本身是不以來jQuery的。           });      }); }
為何這麼迫不及待地調用parser組件的pasrse方法呢?我們找到源碼看一下:
 $.parser = {      auto: true,      onComplete: function(context){},      plugins:['draggable','droppable','resizable','pagination','tooltip',               'linkbutton' ], //這裡僅包含頁面組件      parse: function(context){       var aa = [];       for(var i=0; i<$.parser.plugins.length; i++){ // 逐個處理plugin            var name = $.parser.plugins[i];             // 通過 樣式類名約定,Err,這樣好嗎?            // 侵入性太強,竊以為這是封閉性的做法            var r = $('.easyui-' + name, context);            if (r.length){                  // 假如是  progressbar 組件,name的值是  progressbar                  if (r[name]){                            // r 是jQuery對象,r['progressbar']有效,即已經載入過這個組件                      r[name](); // 調用 r.progressbar() , 每個組件都體現為一個方法                } else { // 如果組件還未載入,載入後再調用                      //  以下為邏輯類比,並非源碼                         easyloader.load(name, function(){        r[name]();  });                 }            }       }}

好吧,清晰明了,easyui已經為我們揭開了面紗。
2 繞開easyloader現在我們已經知道了easyloader的秘密,我們嘗試繞開它,需要完成兩部分工作:一是easyloader做的,我們用下面的代碼替換:
 <link rel="stylesheet" type="text/css" href="progressbar.css">  <script type="text/javascript" src="jquery.progressbar.js"></script>
而是parser做的,我們用下面的代碼替換:
$(function(){       $('#p').progressbar();});
progressbar代碼中引用了parser,用於簡化初始化參數配置,把parser也直接引入。
<script type="text/javascript" src="jquery.parser.js"></script>
頁面代碼重用esayui demo代碼,完整代碼如下:
<html><head>     <meta charset="UTF-8">     <title>Easy ProgressBar</title>     <link rel="stylesheet" type="text/css" href="progressbar.css">     <script type="text/javascript" src="jquery.min.js"></script>     <script type="text/javascript" src="jquery.parser.js"></script>     <script type="text/javascript" src="jquery.progressbar.js"></script>     <script type="text/javascript">      $(function(){           $('#p').progressbar();           $('#p').progressbar('setValue', 90);      });     </script></head><body>     <h2>Easy ProgressBar</h2>     <div id="p" style="width:400px;"></div></body></html>
easyloader 是個優秀的資源載入實現,我們繞開它只是為了加深對模組間關係的理解。現在我們知道了,Dependencies:none並不是真的沒有依賴,而是僅僅依賴了parser。parser是可以繞開的,只要你不使用它提供的工具方法。
3 組件定義我們嘗試分析progressbar源碼,瞭解easyui組件定義的規律。
(function($){// 定義屬性和事件的預設值$.fn.progressbar.defaults = {width: 'auto',height: 22,value: 0,// percentage valuetext: '{value}%',onChange:function(newValue,oldValue){}};// 初始化方法,在入口函數中調用// 這是很典型的一個頁面組件,在初始化的時候增加樣式,增加頁面元素,綁定事件function init(target){  // 增加樣式$(target).addClass('progressbar');// 增加頁面元素以實現功能$(target).html('<div class="progressbar-text"></div><div class="progressbar-value"><div class="progressbar-text"></div></div>');// 頁面大小調整時觸發?force傳true可強制改變大小$(target).bind('_resize', function(e,force){if ($(this).hasClass('easyui-fluid') || force){setSize(target);}// 阻止事件冒泡?return false;});return $(target);}/* 入口函數 */$.fn.progressbar = function(options, param){  // 如果第一個參數是 string 類型,那就是在調用方法  // 形如: $('#x').progressbar('getValue');if (typeof options == 'string'){var method = $.fn.progressbar.methods[options];if (method){return method(this, param);}}// 配置項預設為空白對象options = options || {};// 外掛程式擴充的基本寫法return this.each(function(){// 從緩衝中取狀態資料var state = $.data(this, 'progressbar');if (state){// 如果找到,把新傳入的options合并$.extend(state.options, options);} else {// 新建立一個,並加入緩衝state = $.data(this, 'progressbar', {//$.fn.progressbar.parseOptions(this)是自訂的,稍後看代碼// 這裡可以看到配置資訊的優先順序options: $.extend({}, $.fn.progressbar.defaults, $.fn.progressbar.parseOptions(this), options),bar: init(this) // init()返回的是 $(target)});}$(this).progressbar('setValue', state.options.value);setSize(this);});};// 閉包之內,對$.fn.progressbar函數內可見,對外不可見function setSize(target,width){// 從緩衝中取得配置資訊var opts = $.data(target, 'progressbar').options;// 獲得bar對象,即 init()返回的 $(target)var bar = $.data(target, 'progressbar').bar;if (width) opts.width = width;// parser中定義的bar._size(opts);// 更改進度條顯示bar.find('div.progressbar-text').css('width', bar.width());bar.find('div.progressbar-text,div.progressbar-value').css({height: bar.height()+'px',lineHeight: bar.height()+'px'});}// 提供給使用者調用的方法$.fn.progressbar.methods = {// 調用方式: $('p').progressbar('options').value;// 第一個參數jq已經被progressbar傳了thisoptions: function(jq){return $.data(jq[0], 'progressbar').options;},// 調用方式: $('p').progressbar('resize',width);resize: function(jq, width){return jq.each(function(){setSize(this, width);});},// 調用方式: $('p').progressbar('getValue');getValue: function(jq){return $.data(jq[0], 'progressbar').options.value;},// 調用方式: $('p').progressbar('setValue',90);setValue: function(jq, value){if (value < 0) value = 0;if (value > 100) value = 100;return jq.each(function(){var opts = $.data(this, 'progressbar').options;var text = opts.text.replace(/{value}/, value);var oldValue = opts.value;opts.value = value;$(this).find('div.progressbar-value').width(value+'%');$(this).find('div.progressbar-text').html(text);if (oldValue != value){opts.onChange.call(this, value, oldValue);}});}};// 調用了 $.parser.parseOptions// 有兩處依賴  parser$.fn.progressbar.parseOptions = function(target){return $.extend({}, $.parser.parseOptions(target, ['width','height','text',{value:'number'}]));};})(jQuery);

有兩處依賴parser,感興趣的話,可以看看源碼。

4、小結

easyloader是個優秀的資源載入架構。

parser是easyui的核心,實現了自動載入解析(雖然約定過於死板,不是我喜歡的風格)頁面控制項,同時提供優秀的頁面操作基礎函數(這個價值很大)。

progressbar代碼清晰,結構合理,可以作為自己開發頁面組件的模版。







java程式員javascript要掌握到什水平?

其實那些很炫效果網上都有原始碼,他們用的js架構,如jquery,和ajax架構,如dojo,extjs,dwr等 ,作為程式員只要會寫常用的javascript,如表單的驗證,樹形菜單,捲簾菜單等。和對常用的對象常用的方法必須熟悉,如document,widow,form.我在公司開發,花在前台的時間比背景時間多的多。程式員還要懂css,
 
開發Jquery UI(或者javascript控制項)的資料 注意不是使用javascript控制項 而是開發這些控制項的資料

寫jQuery的外掛程式原理很簡單, 就是寫一個匿名執行函數, 函數中定義了prototype函數, 即為jQuery對象增加了方法, 至於這個方法要做什麼, 就是你外掛程式要實現的東西
網上的例子很多, 也很容易看明白

但是要寫出很好的外掛程式, 還是很考驗js功底和css設計和操作的, 如果你只是想知道jQuery實現外掛程式的原理, 網上的例子很多, 基本看一個就明白
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.