jQuery插件开发方式主要有三种:
- 通过$.extend()来扩展jQuery
- 通过$.fn 向jQuery添加新的方法
- 通过$.widget()应用jQuery UI的部件工厂方式创建
1.$.extend()
这种方式仅仅是在jQuery命名空间上添加了一个静态方法,通过$.extend()创建的方法在调用时直接通过$调用,如:
$.extend({ sayHello: function(name) { console.log('Hello,' + (name ? name : 'Dude') + '!'); } }) $.sayHello(); //调用 Hello,Dude! $.sayHello('Wayou'); //带参调用 Hello,Wayyou
这样就完成了一个简单的jQuery插件。
2.$.fn
基本格式
$.fn.pluginName = function() { //your code goes here }
pluginName为我们的插件方法名字,
比如我们将页面上所有a标签的字体改为红色:
$.fn.myPlugin = function() { //在这里面,this指的是用jQuery选中的元素 //example :$('a'),则this=$('a') this.css('color', 'red'); }//调用$("a").myPlugin();
这里的this指代的是我们在调用插件时用jQuery选择器选中的元素,通常是一个元素集合。比如$("a"),this就指向a.
那么通过jQuery的each()方法就可以处理合集中的每一个元素了,需要注意的是,each()方法中的this指代的是普通的DOM元素。
比如现在我们要在每个链接显示链接的真是地址,首先通过each遍历所有a标签,然后获取href属性的值再加到链接文本后面
更改后我们的插件代码为:
<ul> <li> <a href="http://www.webo.com/liuwayong">我的微博</a> </li> <li> <a href="http://http://www.cnblogs.com/Wayou/">我的博客</a> </li> <li> <a href="http://wayouliu.duapp.com/">我的小站</a> </li> </ul> <p>这是p标签不是a标签,我不会受影响</p> <script src="jquery-1.11.0.min.js"></script> <script src="jquery.myplugin.js"></script> <script type="text/javascript"> $.fn.myPlugin = function() { //在这里面,this指的是用jQuery选中的元素 this.css('color', 'red'); this.each(function() { //对每个元素进行操作 $(this).append(' ' + $(this).attr('href')); })) } $("a").muPlugin(); //调用 </script>
链式调用
我们都知道jQuery一个时常优雅的特性是支持链式调用,选择好DOM元素后可以不断地调用其他方法。
要让插件不打破这种链式调用,只需return一下即可。
$.fn.myPlugin = function() { //在这里面,this指的是用jQuery选中的元素 this.css('color', 'red'); return this.each(function() { //对每个元素进行操作 $(this).append(' ' + $(this).attr('href')); })) }
让插件接收参数
在处理插件参数的接收上,通常使用jQuery的extend方法,上面也提到过,但那是给extend方法传递单个对象的情况下,这个对象会合并到jQuery身上,所以我们就可以在jQuery身上调用新合并对象里包含的方法了,像上面的例子。当给extend方法传递一个以上的参数时,它会将所有参数对象合并到第一个里。同时,如果对象中有同名属性时,合并的时候后面的会覆盖前面的。
利用这一点,我们可以在插件里定义一个保存插件参数默认值的对象,同时将接收来的参数对象合并到默认对象上,最后就实现了用户指定了值的参数使用指定的值,未指定的参数使用插件默认值。
为了演示方便,再指定一个参数fontSize,允许调用插件的时候设置字体大小。
$.fn.myPlugin = function(options) { var defaults = { 'color': 'red', 'fontSize': '12px' }; var settings = $.extend(defaults, options); return this.css({ 'color': settings.color, 'fontSize': settings.fontSize }); }
现在,我们调用的时候指定颜色,字体大小未指定,会运用插件里的默认值12px。
$('a').myPlugin({ 'color': '#2C9929' });
保护好默认参数
注意到上面代码调用extend时会将defaults的值改变,这样不好,因为它作为插件因有的一些东西应该维持原样,另外就是如果你在后续代码中还要使用这些默认值的话,当你再次访问它时它已经被用户传进来的参数更改了。
一个好的做法是将一个新的空对象做为$.extend的第一个参数,defaults和用户传递的参数对象紧随其后,这样做的好处是所有值被合并到这个空对象上,保护了插件里面的默认值。
$.fn.myPlugin = function(options) { var defaults = { 'color': 'red', 'fontSize': '12px' }; var settings = $.extend({},defaults, options);//将一个空对象做为第一个参数 return this.css({ 'color': settings.color, 'fontSize': settings.fontSize }); }
到此,插件可以接收和处理参数后,就可以编写出更健壮而灵活的插件了。若要编写一个复杂的插件,代码量会很大,如何组织代码就成了一个需要面临的问题,没有一个好的方式来组织这些代码,整体感觉会杂乱无章,同时也不好维护,所以将插件的所有方法属性包装到一个对象上,用面向对象的思维来进行开发,无疑会使工作轻松很多。
面向对象的插件开发
为什么要有面向对象的思维,因为如果不这样,你可能需要一个方法的时候就去定义一个function,当需要另外一个方法的时候,再去随便定义一个function,同样,需要一个变量的时候,毫无规则地定义一些散落在代码各处的变量。
还是老问题,不方便维护,也不够清晰。当然,这些问题在代码规模较小时是体现不出来的。
如果将需要的重要变量定义到对象的属性上,函数变成对象的方法,当我们需要的时候通过对象来获取,一来方便管理,二来不会影响外部命名空间,因为所有这些变量名还有方法名都是在对象内部。
接着上面的例子,我们可以把这个插件抽象成一个美化页面的对象,因为他的功能是设置颜色啊字体啊什么的,当然我们还可以加入其他功能比如设置下划线啊什么的。当然对于这个例子抽象成对象有点小题大做,这里仅作演示用。
所以我们新建一个对象命名为Beautifier,然后我们在插件里使用这个对象来编码。
//定义Beautifier的构造函数 var Beautifier = function(ele, opt) { this.$element = ele, this.defaults = { 'color': 'red', 'fontSize': '12px', 'textDecoration':'none' }, this.options = $.extend({}, this.defaults, opt) } //定义Beautifier的方法 Beautifier.prototype = { beautify: function() { return this.$element.css({ 'color': this.options.color, 'fontSize': this.options.fontSize, 'textDecoration': this.options.textDecoration }); } } //在插件中使用Beautifier对象 $.fn.myPlugin = function(options) { //创建Beautifier的实体 var beautifier = new Beautifier(this, options); //调用其方法 return beautifier.beautify(); }
通过上面这样一改造,我们的代码变得更面向对象了,也更好维护和理解,以后要加新功能新方法,只需向对象添加新变量及方法即可,然后在插件里实例化后即可调用新添加的东西。
插件的调用还是一样的,我们对代码的改动并不影响插件其他地方,只是将代码的组织结构改动了而以。
$(function() { $('a').myPlugin({ 'color': '#2C9929', 'fontSize': '20px' }); })
来源:https://www.cnblogs.com/zhengzhigang/p/8386597.html