第一次写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