jQuery插件开发模式
软件开发过程中是需要一定的设计模式来指导开发的,有了模式,我们就能更好地组织我们的代码,并且从这些前人总结出来的模式中学到很多好的实践。
根据《jQuery高级编程》的描述,jQuery插件开发方式主要有三种:
- 通过$.extend()来扩展jQuery
- 通过$.fn 向jQuery添加新的方法
- 通过$.widget()应用jQuery UI的部件工厂方式创建
通常我们使用第二种方法来进行简单插件开发,说简单是相对于第三种方式。第三种方式是用来开发更高级jQuery部件的,该模式开发出来的部件带有很多jQuery内建的特性,比如插件的状态信息自动保存,各种关于插件的常用方法等。而第一种方式又太简单,仅仅是在jQuery命名空间或者理解成jQuery身上添加了一个静态方法而已。所以我们调用通过$.extend()添加的函数时直接通过$符号调用($.myfunction())而不需要选中DOM元素
$.extend({
sayHello: function(name) {
console.log('Hello,' + (name ? name : 'Dude') + '!');
}
})
$.sayHello(); //调用
$.sayHello('Wayou'); //带参调用
上面代码中,通过$.extend()向jQuery添加了一个sayHello函数,然后通过$直接调用。到此你可以认为我们已经完成了一个简单的jQuery插件了。
但是这种方式无法利用jquery 强大的选择器带来的便利,要处理DOM元素以及将插件更好的运用于所选择的元素上,还需要使用第二种开发方式。
插件开发
基本格式:
$.fn.pluginName = function() {
//your code goes here
往 $.fn 上面添加一个方法,名字是我们的插件名称。然后 插件代码在这个方法里面展开。
例:
<ul>
<li>
<a href="http://www.webo.com/liuwayong">我的微博</a>
</li>
<li>
</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">
$(function(){
$('a').myPlugin();
})
</script>
而 jquery.myplugin.js 为我们自定义的插件,内容如下:
$.fn.myPlugin = function() {
//在这里面,this指的是用jQuery选中的元素
this.css('color', 'red');
}
有的时候,当一个页面可能会引用多个插件的时候,为了保证插件的正确,我们可以在我们的插件起始加一个 ; 来表示上一个插件结束,开始新的插件
调用插件的方法 $('a').myPlugin() 相当于 $('a').css('color','red'); 即把所有的a标签转为红色
插件里面的this 指代jquery 选择器返回的集合,而通过调用 jQuery 的.each() 方法可以处理合集中 的每个元素了。在each 方法内部,this指代的时候普通的DOM 元素,所以需要用$包装,如$(this)
$.fn.myPlugin = function() {
//在这里面,this指的是用jQuery选中的元素
this.css('color', 'red');
this.each(function() {
//对每个元素进行操作
$(this).append(' ' + $(this).attr('href'));
}))
}
上面的插件意思:把所有的链接转为红色,并且将每个链接显示真实的链接地址
jquery有一个特性就是 支持链式调用,选择好的DOM元素后可以不断的调用其他方法,要不打破这种链式调用,需要把最后的值 return 一下
而一个好的插件是可以让使用者随意定制的,所以需要在编写插件是要考虑的全面一些,尽量提供合适的参数。比如,我们可以让用户定义显示什么颜色。需要让使用者在调用的时候传入一个参数,我们在插件代码里面接受即可。为了灵活,使用者可以不传递参数,插件里面采用默认值。为了保护好默认参数,所以第一个值使用新的空对象{}
$.fn.myPlugin = function(options) {
var defaults = {
'color': 'red',
'fontSize': '12px'
};
var settings = $.extend({},defaults, options);
return this.css({
'color': settings.color,
'fontSize': settings.fontSize
});
}
在处理插件参数的接收上,通常使用Jquery的extend方法。当给extend方法传递一个以上的参数时,它会将所有参数合并到第一个里,同时,如果对象中有同名属性时,合并的时候后面的会覆盖前面的。
面向对象的插件开发
需要一个方法是就去定义一个function,需要变量是就去定义一个变量,这样不方便维护,也不够清晰。一旦代码较多的时候,还是使用面向对象的思维比较好。
将需要的重要变量定义到对象的属性上,函数变成方法,当我们需要的时候通过对象来获取,一来方便管理,二来不会影响外部命名空间,因为变量名和方法名都在对象内部
(function(){
//定义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();
}
});
在写任意js代码时都应该注意 不要污染全局命名空间。因为随着代码的变多,全局范围的变量很难维护,也容易跟别人的代码有冲突。最好始终用 自调用匿名函数 包裹代码
如上面的例子,我们调整了代码的组织结构,并将其用自调用匿名函数包裹。自调用匿名函数里面的代码会在第一时间执行,方便后面的代码使用插件。
为了防止多个插件同时使用时,有的插件没有用分号结尾,最好在代码开始加个分号 ;
而,原有的系统变量也有可能被更改,所以最好将系统变量以参数形式传递到插件内部。这样插件内部就有一个局部的引用,可以提高访问速度,会有些许性能提升
结构如下:
;(function($,window,document,undefined){
//我们的代码。。
//blah blah blah...
})(jQuery,window,document);
而至于这个undefined,稍微有意思一点,为了得到没有被修改的undefined,我们并没有传递这个参数,但却在接收时接收了它,因为实际并没有传,所以‘undefined’那个位置接收到的就是真实的'undefined'了。
最终,这个插件应该为:
;(function($, window, document,undefined) {
//定义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();
}
})(jQuery, window, document);
作者:panie