Require.js中使用jQuery 插件请查看http://www.css88.com/archives/4826
扩展jQuery插件和方法的做用是很是强大的,它能够节省大量开发时间。这篇文章将概述jQuery插件开发的基本知识,最佳作法和常见的陷阱。css
入门
编写一个jQuery插件开始于给jQuery.fn加入新的功能属性,此处添加的对象属性的名称就是你插件的名称:安全
- jQuery.fn.myPlugin =function(){
- //你本身的插件代码
- };
用户很是喜欢的$符号哪里去了? 它仍然存在,可是,为了不和其余JavaScript库冲突,咱们最好将jQuery传递给一个自我执行的封闭程序,jQuery在此程序中映射为$符号,这样能够避免$号被其余库覆写。架构
- (function($){
- $.fn.myPlugin =function(){
- //你本身的插件代码
- };
- })(jQuery);
在这个封闭程序中,咱们能够无限制的使用$符号来表示jQuery函数。app
环境
如今,咱们能够开始编写实际的插件代码。 可是,在这以前,咱们必须得对插件所处的环境有个概念。 在插件的范围里, this关键字表明了这个插件将要执行的jQuery对象, 这里容易产生一个广泛的误区,由于在其余包含callback的jQuery函数中,this关键字表明了原生的DOM元素。这经常会致使开发者误将this关键字无谓的包在jQuery中,以下所示。ide
- (function($){
- $.fn.myPlugin =function(){
- //此处没有必要将this包在$号中如$(this),由于this已是一个jQuery对象。
- //$(this)等同于 $($('#element'));
- this.fadeIn('normal',function(){
- //此处callback函数中this关键字表明一个DOM元素
- });
- };
- })(jQuery);
- $('#element').myPlugin();
基础知识
如今,咱们理解了jQuery插件的基础知识,让咱们写一个插件,作一些事情。函数
- (function($){
- $.fn.maxHeight =function(){
- var max =0;
- this.each(function(){
- max =Math.max(max, $(this).height());
- });
- return max;
- };
- })(jQuery);
- var tallest = $('div').maxHeight();//返回高度最大的div元素的高度
这是一个简单的插件,利用.height()返回页面中高度最大的div元素的高度。ui
维护Chainability
不少时候,一个插件的意图仅仅是以某种方式修改收集的元素,并把它们传递给链中的下一个方法。 这是jQuery的设计之美,是jQuery如此受欢迎的缘由之一。 所以,要保持一个插件的chainability,你必须确保你的插件返回this关键字。this
- (function($){
- $.fn.lockDimensions =function(type){
- returnthis.each(function(){
- var $this = $(this);
- if(!type || type =='width'){
- $this.width($this.width());
- }
- if(!type || type =='height'){
- $this.height($this.height());
- }
- });
- };
- })(jQuery);
- $('div').lockDimensions('width').CSS('color','red');
因为插件返回this关键字,它保持了chainability,这样jQuery收集的元素能够继续被jQuery方法如.css控制。 所以,若是你的插件不返回固有的价值,你应该老是在其做用范围内返回this关键字。 此外,你可能会推断出,传递给插件的参数将会在插件的做用范围内被传递。 所以,在前面的例子,字符串’width’变成了插件的类型参数。spa
默认值和选项
对于比较复杂的和提供了许多选项可定制的的插件,最好有一个当插件被调用的时候能够被拓展的默认设置(经过使用$.extend)。 所以,相对于调用一个有大量参数的插件,你能够调用一个对象参数,包含你了你想覆写的设置。prototype
- (function($){
- $.fn.tooltip =function(options){
- //建立一些默认值,拓展任何被提供的选项
- var settings = $.extend({
- 'location':'top',
- 'background-color':'blue'
- }, options);
- returnthis.each(function(){
- // Tooltip插件代码
- });
- };
- })(jQuery);
- $('div').tooltip({
- 'location':'left'
- });
在这个例子中,调用tooltip插件时覆写了默认设置中的location选项,background-color选项保持默认值,因此最终被调用的设定值为:
- {
- 'location':'left',
- 'background-color':'blue'
- }
这是一个很灵活的方式,提供一个高度可配置的插件,而无需开发人员定义全部可用的选项。
命名空间
正确命名空间你的插件是插件开发的一个很是重要的一部分。 正确的命名空间,能够保证你的插件将有一个很是低的机会被其余插件或同一页上的其余代码覆盖。 命名空间也使得你的生活做为一个插件开发人员更容易,由于它能够帮助你更好地跟踪你的方法,事件和数据。
插件方法
在任何状况下,一个单独的插件不该该在jQuery.fn
jQuery.fn对象里有多个命名空间。
- (function($){
- $.fn.tooltip =function(options){
- // this
- };
- $.fn.tooltipShow =function(){
- // is
- };
- $.fn.tooltipHide =function(){
- // bad
- };
- $.fn.tooltipUpdate =function(content){
- // !!!
- };
- })(jQuery);
这是不被鼓励的,由于它$.fn
使$.fn命名空间混乱。 为了解决这个问题,你应该收集对象文本中的全部插件的方法,经过传递该方法的字符串名称给插件以调用它们。
- (function($){
- var methods ={
- init:function(options){
- // this
- },
- show:function(){
- // is
- },
- hide:function(){
- // good
- },
- update:function(content){
- // !!!
- }
- };
- $.fn.tooltip =function(method){
- // 方法调用
- if(methods[method]){
- return methods[method].apply(this,Array.prototype.slice.call(arguments,1));
- }elseif(typeof method ==='object'||!method){
- return methods.init.apply(this, arguments);
- }else{
- $.error('Method'+ method +'does not exist on jQuery.tooltip');
- }
- };
- })(jQuery);
- //调用init方法
- $('div').tooltip();
- //调用init方法
- $('div').tooltip({
- foo:'bar'
- });
- // 调用hide方法
- $('div').tooltip('hide');
- //调用Update方法
- $('div').tooltip('update','This is the new tooltip content!');
这种类型的插件架构容许您封装全部的方法在父包中,经过传递该方法的字符串名称和额外的此方法须要的参数来调用它们。 这种方法的封装和架构类型是jQuery插件社区的标准,它被无数的插件在使用,包括jQueryUI中的插件和widgets。
事件
一个不为人知bind方法的功能即容许绑定事件命名空间。 若是你的插件绑定一个事件,一个很好的作法是赋予此事件命名空间。 经过这种方式,当你在解除绑定的时候不会干扰其余可能已经绑定的同一类型事件。 你能够经过追加命名空间到你须要绑定的的事件经过 ‘.<namespace>’。
- (function($){
- var methods ={
- init:function(options){
- returnthis.each(function(){
- $(window).bind('resize.tooltip', methods.reposition);
- });
- },
- destroy:function(){
- returnthis.each(function(){
- $(window).unbind('.tooltip');
- })
- },
- reposition:function(){
- //...
- },
- show:function(){
- //...
- },
- hide:function(){
- //...
- },
- update:function(content){
- //...
- }
- };
- $.fn.tooltip =function(method){
- if(methods[method]){
- return methods[method].apply(this,Array.prototype.slice.call(arguments,1));
- }elseif(typeof method ==='object'||!method){
- return methods.init.apply(this, arguments);
- }else{
- $.error('Method '+ method +' does not exist on jQuery.tooltip');
- }
- };
- })(jQuery);
- $('#fun').tooltip();
- //一段时间以后... ...
- $('#fun').tooltip('destroy');
在这个例子中,当tooltip经过init方法初始化时,它将reposition方法绑定到resize事件并给reposition非那方法赋予命名空间经过追加.tooltip。 稍后, 当开发人员须要销毁tooltip的时候,咱们能够同时解除其中reposition方法和resize事件的绑定,经过传递reposition的命名空间给插件。 这使咱们可以安全地解除事件的绑定并不会影响到此插件以外的绑定。
数据
一般在插件开发的时候,你可能须要记录或者检查你的插件是否已经被初始化给了一个元素。 使用jQuery的data方法是一个很好的基于元素的记录变量的途径。尽管如此,相对于记录大量的不一样名字的分离的data, 使用一个单独的对象保存全部变量,并经过一个单独的命名空间读取这个对象不失为一个更好的方法。
- (function($){
- var methods ={
- init:function(options){
- returnthis.each(function(){
- var $this = $(this),
- data = $this.data('tooltip'),
- tooltip = $('<div />',{
- text: $this.attr('title')
- });
- // If the plugin hasn't been initialized yet
- if(!data){
- /*
- Do more setup stuff here
- */
- $(this).data('tooltip',{
- target: $this,
- tooltip: tooltip
- });
- }
- });
- },
- destroy:function(){
- returnthis.each(function(){
- var $this = $(this),
- data = $this.data('tooltip');
- // Namespacing FTW
- $(window).unbind('.tooltip');
- data.tooltip.remove();
- $this.removeData('tooltip');
- })
- },
- reposition:function(){
- // ...
- },
- show:function(){
- // ...
- },
- hide:function(){
- // ...
- },
- update:function(content){
- // ...
- }
- };
- $.fn.tooltip =function(method){
- if(methods[method]){
- return methods[method].apply(this,Array.prototype.slice.call(arguments,1));
- }elseif(typeof method ==='object'||!method){
- return methods.init.apply(this, arguments);
- }else{
- $.error('Method '+ method +' does not exist on jQuery.tooltip');
- }
- };
- })(jQuery);
将数据经过命名空间封装在一个对象中,能够更容易的从一个集中的位置读取全部插件的属性。
总结和最佳作法
编写jQuery插件容许你作出库,将最有用的功能集成到可重用的代码,能够节省开发者的时间,使开发更高效。 开发jQuery插件时,要牢记:
- 始终包裹在一个封闭的插件:
- (function($){
- /* plugin goes here */
- })(jQuery);
- 不要冗余包裹this关键字在插件的功能范围内
- 除非插件返回特定值,不然老是返回this关键字来维持chainability 。
- 传递一个可拓展的默认对象参数而不是大量的参数给插件。
- 不要在一个插件中屡次命名不一样方法。
- 始终命名空间的方法,事件和数据。