jquery插件开发模式
jquery插件一般有三种开发方式:
通过$.extend()来扩展jQuery
通过$.fn 向jQuery添加新的方法
通过$.widget()应用jQuery UI的部件工厂方式创建
第一种$.extend()相对简单,一般很少能够独立开发复杂插件,第三种是一种高级的开发模式,本文也不做介绍。第二种则是一般插件开发用到的方式,本文着重讲讲第二种。
插件开发
第二种插件开发方式一般是如下定义
$.fn.pluginName = function() { //your code here }
插件开发,我们一般运用面向对象的思维方式
例如定义一个对象
var Haorooms= function(el, opt) { this.$element = el, this.defaults = { 'color': 'red', 'fontSize': '12px', 'textDecoration':'none' }, this.options = $.extend({}, this.defaults, opt) } //定义haorooms的方法 haorooms.prototype = { changecss: function() { return this.$element.css({ 'color': this.options.color, 'fontSize': this.options.fontSize, 'textDecoration': this.options.textDecoration }); } }
$.extend({}, this.defaults, opt)有{}主要是为了创建一个新对象,保留对象的默认值。
$.fn.myPlugin = function(options) { //创建haorooms的实体 var haorooms= new Haorooms(this, options); //调用其方法 return Haorooms.changecss(); }
调用这个插件直接如下就可以
$(function() { $('a').myPlugin({ 'color': '#2C9929', 'fontSize': '20px' }); })
上述开发方法的问题
上面的开发方法存在一个严重的问题,就是定义了一个全局的Haorooms,这样对于插件的兼容等等各个方面都不好。万一别的地方用到了Haorooms,那么你的代码就悲催了!现在我们把上面的代码包装起来,用一个自调用匿名函数(有时又叫块级作用域或者私有作用域)包裹,就不会出现这个问题了!包括js插件的开发,也是一样的,我们用一个自调用匿名函数把自己写的代码包裹起来,就可以了!包裹方法如下:
(function(){ })()
用上面的这个包裹起来,就可以了。
但是还有一个问题,当我们研究大牛的代码的时候,前面经常看到有“;”,那是为了避免代码合并等不必要的错误。
例如,我们随便定义一个函数:
var haoroomsblog=function(){ } (function(){ })()
由于haoroomsblog这个函数后面没有加分号,导致代码出错,为了避免这类情况的发生,通常这么写!
;(function(){ })()
把你的插件代码包裹在上面里面,就是一个简单的插件了。(注js插件和jquery插件都是如此)
还有一个问题
把你的插件包裹在
;(function(){ })()
基本上可以说是完美了。但是为了让你开发的插件应用更加广泛,兼容性更加好,还要考虑到用插件的人的一些特殊的做法,例如,有些朋友为了避免jquery和zeptojs冲突,将jquery的前缀“$”,修改为“jQuery”,还有些朋友将默认的document等方法修改。为了让你的插件在这些东西修了了的情况下照常运行,那么我们的做法是,把代码包裹在如下里面:
;(function($,window,document,undefined){ //我们的代码。。 })(jQuery,window,document);
就可以避免上面的一些情况了!
优秀的示例
下面,我们有了一个插件的基本层次:
(function($) { var privateFunction = function() { // 代码在这里运行 } var methods = { init: function(options) { return this.each(function() { var $this = $(this); var settings = $this.data('pluginName'); if(typeof(settings) == 'undefined') { var defaults = { propertyName: 'value', onSomeEvent: function() {} } settings = $.extend({}, defaults, options); $this.data('pluginName', settings); } else { settings = $.extend({}, settings, options); } // 代码在这里运行 }); }, destroy: function(options) { return $(this).each(function() { var $this = $(this); $this.removeData('pluginName'); }); }, val: function(options) { var someValue = this.eq(0).html(); return someValue; } }; $.fn.pluginName = function() { var method = arguments[0]; if(methods[method]) { method = methods[method]; arguments = Array.prototype.slice.call(arguments, 1); } else if( typeof(method) == 'object' || !method ) { method = methods.init; } else { $.error( 'Method ' + method + ' does not exist on jQuery.pluginName' ); return this; } return method.apply(this, arguments); } })(jQuery);
你可能会注意到,我所提到代码的结构和其他插件代码有很大的不同。根据你的使用和需求的不同,插件的开发方式也可能会呈现多样化。我的目的是澄清代码中的一些概念,足够让你找到适合自己的方法去理解和开发一个jQuery插件。
现在,来解剖我们的代码吧!
容器:一个即时执行函数
根本上来说,每个插件的代码是被包含在一个即时执行的函数当中,如下:
(function(arg1, arg2) { // 代码 })(arg1, arg2);