您的位置:首页 > Web前端 > JQuery

jquery插件编写学习小结

2016-04-09 13:19 936 查看
编写插件的目的是给已经有的一系列方法或函数做一个封装,以便在其他地方重复使用,方便后期维护和提高开发效率。



一、插件的种类

jQuery的插件主要分为3种类型。

1、封装对象方法的插件

2、封装全局函数的插件

3、选择器插件

这里我们主要讨论第一种插件的开发流程。

封装对象方法的插件:

这种插件是将对象方法封装起来,用于对通过选择器获取的jQuery对象进行操作,是最常见的一种插件,有95%以上的插件都是这种类型的插件。

二、插件的基本要点

1、所有对象方法都应当附加到jQuery.fn上,而所有全局函数都应当附加到jQuery对象本身上。

2、在插件内部,this指向的是当前通过选择器获取的jQuery对象,而不是DOM元素。

3、所有方法或函数插件,都应当以分号结尾,为了更稳妥些,甚至可以再插件头部也加上一个分号,以免他们的不规范代码给插件带来影响。

4、插件应当返回一个jQuery对象,以保证链式操作。

5、闭包的使用。

三、插件中的闭包

闭包:简单来说,当一个内部函数在包含他们的外部函数之外被调用时,就会形成闭包。

利用闭包的特性,既可以避免内部临时变量影响到全局空间,又可以在插件内部继续使用$作为jQuery的别名。常见的jQuery插件都是这样的形式:

;(function ($) {
//...
})(jQuery);


再看看这段代码:

;(function ($) {
//定义一个局部变量foo,仅函数内部可以访问,外部无法访问
var foo;
var bar = function(){
//...
}
//下面这句话相当于增加了一个jQuery对象上的全局函数BAR。可以通过$.BAR()的方式来访问内部定义的函数bar(),并且内部函数bar()也能访问foo
$.BAR = bar;
})(jQuery);


其实这里与我之前写的一篇介绍模块化编程的博文很相似,都用到了闭包的盖概念,不过在模块化编程中通过闭包可以拓展模块方法,而这里是增加$对象上的方法,也就是jQuery全局函数插件。

四、jQuery.extend()方法

jQuery提供了两个用于扩展jQuery功能的方法,即jQuery.fn.extend方法和jQuery.extend()方法。前者用于可扩展之前提到的三种类型插件中的第一种,后者用于扩展后两种插件。这里要介绍的是jQuery.extend()方法除了可以用于扩展jQuery对象之外,还有一个很强大的功能,就是用于扩展已有的Object对象。

jQuery.extend(target,obj1,obj2,...objn);


用一个或多个对象来扩展一个对象,然后返回被扩展的对象。

举个栗子:

var settings = { validate: false,limit: 5,name: "foo" };
var options= { validate: true,name: "bar" };
var newOptions = jQuery.extend(settings,options);


结果为:

newOptions = { validate: true,limit: 5,name: "bar" };


显然,这个方法的特性可以很方便的用传入的参数来覆盖默认值,在插件的编写中会经常用到。

五、编写jQuery插件

鉴于之前在实习期间(采遗网电商平台)写个人中心栏目时经常会遇到各种各样的表格,为了避免重复的工作,遂学习写了一个具有表格隔行变色、点击选中变色简单功能的插件。

不然每次都需要重复下面类似代码:

$("tbody>tr:odd").addClass("odd");
$("tbody>tr:even").addClass("even");
$("tbody>tr:has(:checked)").addClass("selected");
$("tbody>tr").click(function () {
var hasSelected = $(this).hasClass("selected");
$(this)[hasSelected?"removeClass":"addClass"]  ("selected").find(':checkbox').prop('checked',!hasSelected);
});


功能不大,但也算是了解了插件的具体开发流程。

首先,我们建立一个新的文件jquery.tableBgColor.js,把插件方法取名tableBgColor,然后搭好框架:

;(function ($) {
$.fn.extend({
"tableBgColor":function(options){
//设置默认值
options= $.extend({
odd:"odd",
even:"even",
selected:"selected"
},options);

//...插件代码

return this;//返回jQuery对象,保证链式操作
})
}
});

})(jQuery);


现在,我们的目的应该是使用选择器选择某个表格,执行tableBgColor()方法后,将对应表格内的tr元素都进行各行变色,并且点击某一行之后也会变色,并且选中对应行内的checkbox。

因此,只需将之前会重复的代码稍作修改放入框架中:

;(function ($) {
$.fn.extend({
"tableBgColor":function(options){
//each()方法遍历匹配元素,因为可能匹配的元素不止一个
return this.each(function () {
//设置默认值
options= $.extend({
odd:"odd",
even:"even",
selected:"selected"
},options);

$("tbody>tr:odd",this).addClass(options.odd);
$("tbody>tr:even",this).addClass(options.even);
$("tbody>tr:has(:checked)",this).addClass("selected");
$("tbody>tr",this).click(function () {
var hasSelected = $(this).hasClass(options.selected);
$(this)[hasSelected?"removeClass":"addClass"](options.selected).find(':checkbox').prop('checked',!hasSelected);//注意这里用的是prop而不是attr
});

return this;
})
}
});

})(jQuery);


此时,插件就完成了,现在来测试这个插件。构造表格,id为test_table:

<table width="100%" style="table-layout: fixed" id="test_table">
//...此处省略
</table>


设置相应的CSS类:

table{
text-align: left;
border-spacing: 0;
border-collapse: collapse;
}
td,th{
border: 1px solid #e2e2e2;
padding: 3px;
}
th{
background-color: #1B6540;
color: #fff;
}
.odd{
background-color: #4FA46B;
}
.even{
background-color: #8ECE9F;
}
.selected{
background-color: #ecb6c4;
}


引入插件文件:

<script src="jquery.min.js"></script>
<script src="jquery.tableBgColor.js"></script>


调用插件方法:

$(function () {
$("#test_table").tableBgColor();
})


得到如下效果:



点击某一行:



检查连试操作功能:

$("#test_table").tableBgColor().find("th").css("background-color","red");


头部变为红色:



大功告成,完美!

现在你可能会觉得有点小缺陷,插件里没有写到如何解决冲突(conflict)问题,解决这个问题并不难,只需将之前的代码更改如下:

;(function ($) {
var old = $.fn.tableBgColor;//先将之前的即将被覆盖的方法保存在old中

//注意,换了一种定义插件的方法,以便后面$.fn.tableBgColor.noConflict能正常调用tableBgColor方法
$.fn.tableBgColor = function(options){
return this.each(function () {
//设置默认值
options= $.extend({
odd:"odd",
even:"even",
selected:"selected"
},options);

$("tbody>tr:odd",this).addClass(options.odd);
$("tbody>tr:even",this).addClass(options.even);
$("tbody>tr:has(:checked)",this).addClass("selected");
$("tbody>tr",this).click(function () {
var hasSelected = $(this).hasClass(options.selected);
$(this)[hasSelected?"removeClass":"addClass"](options.selected).find(':checkbox').prop('checked',!hasSelected);
});
return this;
})
}
//定义tableBgColor对象的noConflict方法,使得执行这个方法后tableBgColor方法会还原成之前old中所保留的方法
$.fn.tableBgColor.noConflict = function(){
$.fn.tableBgColor = old;
return this;
}
})(jQuery);


你可能还会觉得有点小瑕疵,该表格还无法进行全选功能,当然也可以自己再动手写一个全选功能的插件,不过需要注意的是全选功能涉及到的元素可能较多,在进行html结构设计的时候最好配合插件的功能编写,这里就不再多说。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息