第一次写jquery插件,在这里做一个记录和积累。所有文章均同步到我的博客
写jQuery插件的目的
主要是对一些重复使用率高的一系列方法或函数做封装,能够提高开发的效率,也方便后期维护
写插件前需要知道的预备知识
jQuery插件有哪几种类型?
-
封装对象方法的插件(对象级别)
这类插件是最常见的一种,即将对象方法进行封装,然后通过选择器获取的jQuery对象进行操作。
用法:$('#id').myPlugin()
。 -
封装全局函数的插件(类级别)
即将独立的函数加到jquery命名空间下, 拓展jQuery类,典型例子
$.ajax()
用法:$.myPlugin()
jQuery插件中的闭包
常见的jQuery插件形式如下:
//为了更好的兼容性,开始有个分号
;(function ($) {
/*你的插件代码*/
})(jQuery);
利用闭包的特性,避免内部变量影响全局空间,通过形参$将jQuery传递给匿名函数,在插件内部就可以使用$作为jQuery的别名。
jQuery插件的机制
//扩展第一种类型(即对象级别)的插件
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。
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);
}
动手编写一个jQuery插件
以分页插件作为练习,体会了上面的知识点,部分地方还有待优化
首先是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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。