第一次寫jquery插件,在這裏作一個記錄和積累。全部文章均同步到個人博客javascript
主要是對一些重複使用率高的一系列方法或函數作封裝,可以提升開發的效率,也方便後期維護html
封裝對象方法的插件(對象級別)java
這類插件是最多見的一種,即將對象方法進行封裝,而後經過選擇器獲取的jQuery對象進行操做。
用法:$('#id').myPlugin()
。jquery
封裝全局函數的插件(類級別)git
即將獨立的函數加到jquery命名空間下, 拓展jQuery類,典型例子$.ajax()
用法:$.myPlugin()
github
常見的jQuery插件形式以下:ajax
//爲了更好的兼容性,開始有個分號 ;(function ($) { /*你的插件代碼*/ })(jQuery);
利用閉包的特性,避免內部變量影響全局空間,經過形參$將jQuery傳遞給匿名函數,在插件內部就可使用$做爲jQuery的別名。api
//擴展第一種類型(即對象級別)的插件 jQuery.fn.extend() //擴展第二種類型(即類級別)的插件 jQuery.extend()
extend()方法接受一個Object類型的參數,key值爲函數名或方法名,value值爲函數主體。閉包
//給jQuery對象添加方法,就是對jQuery.prototype擴展,給jQuery類添加成員方法 $.fn.extend({ getInputText: function(){ $(this).click(function(){ alert($(this).val()); }); } }); //$("#username").getInputText(); //給jQuery類擴展,至關於給jQuery添加靜態方法 $.extend({ add: function(a, b){return a + b;} }); // $.add(1, 2); //return 3
除了能夠擴展jQuery對象,$.extend(default, options)
還能夠擴展Object對象,用傳入的參數options覆蓋默認值default。app
function myPlugin(options) { var defaults = { color: 'blue', width: '100' }; options = $.extend(defaults, options); } //myPlugin({color: 'white'}); //myPlugin({color: 'white', width: '200'}); //myPlugin();
插件名推薦命名爲jquery.插件名.js
,好比jquery.myPlugin.js
插件內部this
的指向爲將要執行的jquery對象,而在其餘包含callback的jQuery函數裏,this指向原生DOM元素。
(function($) { $.fn.myPlugin = function () { //此處沒有必要將this包在$號中如$(this),由於this已是一個jQuery對象。 //$(this)等同於 $($('#element')); this.fadeIn('normal', function () { //此處callback函數中this關鍵字表明一個DOM元素 }); }; })(jQuery);
用this.each對全部元素進行遍歷,同時爲了保持插件的鏈式調用,確保插件返回this關鍵字
(function($) { $.fn.myPlugin = function () { return this.each(function () { //此處是你的插件代碼 }); }; })(jQuery);
保護好默認參數
回顧上面講$.extend(default, options)
時舉的例子
``` function myPlugin(options) { var defaults = { color: 'blue', width: '100' }; options = $.extend(defaults, options); } ```
這種寫法很差,調用extend時會改變defaults的值,defaults做爲插件默認值應維持原狀,若後續想再使用默認值,會發現它已被用戶傳來的值所更改。
因此更好的寫法是把一個新的空對象做爲extend的第一個參數,接下來是defaults和options,那麼全部值合併後保存到了這個空對象上,保護了默認值。
function myPlugin(options) { var defaults = { color: 'blue', width: '100' }; options = $.extend({}, defaults, options); }
以分頁插件做爲練習,體會了上面的知識點,部分地方還有待優化
首先是HTML結構
//要插入頁碼的容器 <div id="pager"></div> <p class="page-text"></p>
CSS結構
* {margin:0;padding: 0;} ul {list-style: none;} .page {height:40px;overflow: hidden;margin-top: 20px;} .page li {display: inline-block;*display: inline;*zoom:1;border: 1px solid #CCC;background-color: #FFF;margin-right: 5px;padding: 5px 8px;cursor: pointer;} .page li:hover {border:1px solid #1B4CA6;background-color: #BBD1F9;} .page li.current {border:1px solid #1B4CA6;background-color: #BBD1F9;} .page li.disable {border:1px solid #EEE;color:#999;cursor: auto;background-color: #FFF;} .page-text {margin-top: 10px;} .page-text strong {color: #78C6E2;margin-left: 3px;margin-right: 3px;}
js
的結構
;(function($) { var defaults = { pagecurrent: 1, //當前頁碼 pagecount:1, //頁碼總數 first_text: '首頁', //首頁按鈕的文字可自定義 prev_text: '上一頁', //上一頁按鈕的文字可自定義 next_text: '下一頁', //下一頁按鈕的文字可自定義 last_text: '尾頁', //尾頁按鈕的文字可自定義 max_per_page: 10 //每屏最多顯示多少個頁碼 }; $.fn.pager = function(options) { var options = $.extend({}, defaults, options); return this.each(function() { $(this).empty().append(renderPage(options)); }); } function renderPage(opts) { var pagecurrent = parseInt(opts.pagecurrent); var pagecount = parseInt(opts.pagecount); var btncallback = opts.btncallback; var max_per_page = parseInt(opts.max_per_page); var first_text = opts.first_text; var prev_text = opts.prev_text; var next_text = opts.next_text; var last_text = opts.last_text; //頁碼wrap var pageWrap = $('<ul class="page"></ul>'); //添加第一頁和上一頁按鈕 pageWrap.append(renderBtn('first', first_text, pagecurrent, pagecount, btncallback)) .append(renderBtn('prev',prev_text, pagecurrent, pagecount, btncallback)); //控制一屏最多顯示n條頁碼 var startNum = 1; var endNum = max_per_page; var point = Math.ceil((endNum - startNum) / 2); if (pagecurrent > point) { startNum = pagecurrent - point; endNum = pagecurrent + point; } if (endNum > pagecount) { startNum = pagecount - max_per_page + 1; endNum = pagecount; } if (startNum < 1) { startNum = 1; } //渲染頁碼列表 for (var pagenumber = startNum; pagenumber <= endNum; pagenumber++) { var pagebtn = $('<li>'+ pagenumber +'</li>'); if (pagenumber == pagecurrent) { pagebtn.addClass('current'); } else { pagebtn.click(function() { btncallback(this.innerHTML); }); } pageWrap.append(pagebtn); } //渲染下一頁和尾頁按鈕 pageWrap.append(renderBtn('next', next_text, pagecurrent, pagecount, btncallback)) .append(renderBtn('last', last_text, pagecurrent, pagecount, btncallback)); return pageWrap; } //首頁,上一頁,下一頁,尾頁按鈕的方法 function renderBtn(btntype, btntext, pagecurrent, pagecount, btncallback) { var button = $('<li>'+ btntext +'</li>'); var destPage = 1; switch (btntype) { case 'first': destPage = 1; break; case 'prev': destPage = pagecurrent - 1; break; case 'next': destPage = pagecurrent + 1; break; case 'last': destPage = pagecount; } if (btntype == 'first' || btntype == 'prev') { if (pagecurrent <= 1) { button.addClass('disable'); } else { button.click(function() { btncallback(destPage); }); } } else { if (pagecurrent >= pagecount) { button.addClass('disable'); } else { button.click(function() { btncallback(destPage); }); } } return button; } })(jQuery);
調用
//Google的須要翻一下牆,你懂的-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script> <script src="jquery.pager.js" type="text/javascript"></script> <script type="text/javascript"> $(function(){ $('#pager').pager({ pagecurrent:1, pagecount:20, btncallback:pageClickCallback , //first_text: 'first' }); }); pageClickCallback = function(pageclickednumber){ $('#pager').pager({ pagecurrent:pageclickednumber, pagecount:20, btncallback:PageClick, //first_text: 'first' }); $('.page-text').html('當前是第<strong>'+pageclickednumber+'</strong>頁'); } </script>
顯示結果
查看 demo