1,开始

可以通过为jQuery.fn增加一个新的函数来编写jQuery插件。属性的名字就是你的插件的名字:

   jQuery.fn.myPlugin = function(){
//开始写你的代码吧!
};

但是,那惹人喜爱的美元符号$哪里去了?她就是jQuery,但是为了确保你的插件与其他使用$的库不冲突,最好使用一个立即执行的匿名函数,这个匿名函数的参数是jQuery,这样其他的库就可以放心的使用$符号了。

  (function( $ ){
$.fn.myPlugin = function() {
// 开始吧!
};
})( jQuery );

这样更好了就。在闭包内,可以放心的使用$符号了~

2,上下文

现在已经可以编写我们的代码了,但是编写之前,我必须说一说上下文。在插件内部的范围中,this关键字指向的是jQuery对象。人们很容易误解这一点,因为在正常使用jQuery的时候,this通常指向的是一个DOM元素。不了解这一点,会经常使用$又包装了一次。

(function( $ ){
$.fn.myPlugin = function() {
// 没有必要使用$(this)
// $(this) 跟 $($('#element'))是一样的
this.fadeIn('normal', function(){
//这里的this指的就是一个DOM元素了
});
};
})( jQuery );
$('#element').myPlugin();

3,基本开发

接下来写一个能用的插件吧。

 (function( $ ){
$.fn.maxHeight = function() {
var max = 0;
this.each(function() {
max = Math.max( max, $(this).height() );
});
return max;
};
})( jQuery );
var tallest = $('div').maxHeight();

这是一个简单的插件,通过调用height()返回页面上height最大的div的height。

4,维护链式开发的特性

上一个例子是返回了一个整数,但是大多数情况下,一个插件紧紧是修改收集到的元素,然后返回这个元素让链条上的下一个使用。这是jQuery设计的精美之处,也是jQuery如此流行的原因之一。为了保证可链式,你必须返回this。

 (function( $ ){
$.fn.lockDimensions = function( type ) {
return this.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,所以保证了可链式,从而可以继续使用jQuery方法进行修改,如css()。如果你的插件如果不是返回一个简单值,你通常应该返回this。而且,正如你可能想到的,你传进去的参数也可以在你的插件中访问。所以在这个例子中,可以访问到type。

5,默认值和选项

为了一些复杂的,可订制的插件,最好提供一套默认值,在被调用的时候扩展默认值。这样,调用函数的时候就不用传入一大堆参数,而是传入需要被替换的参数。你可以这样做:

 (function( $ ){
$.fn.tooltip = function( options ) {
var settings = {
'location' : 'top',
'background-color' : 'blue'
};
return this.each(function() {
// 如果存在选项,则合并之
if ( options ) {
$.extend( settings, options );
}
// 其他代码咯
});
};
})( jQuery );
$('div').tooltip({'location':'left'});

在这个例子中,调用插件后,默认的location会被替换城'left',而background-color还是'blue'。这样可以保证高度可配置性,而不需要开发者定义所有可能的选项了。

6,命名空间

正确的命名空间对于插件开发十分重要,这样能确保你的插件不被其他插件重写,也能避免被页面上其他代码重写。命名空间可以使你更长寿,因为你能记录你自己的方法,事件,数据等。

a,插件方法

在任何情况下,都不要在一个插件中为jQuery.fn增加多个方法。如:

 (function( $ ){
$.fn.tooltip = function( options ) { // 这样 };
$.fn.tooltipShow = function( ) { // 是 };
$.fn.tooltipHide = function( ) { // 不好的 };
$.fn.tooltipUpdate = function( content ) { // 同学! };
})( jQuery );

不推荐这样使用,搞乱了$.fn命名空间。要纠正之,你可以把所有的方法放进一个对象中,然后通过不同的参数来调用。

(function( $ ){
var methods = {
init : function( options ) { // THIS },
show : function( ) { // IS },
hide : function( ) { // GOOD },
update : function( content ) { // !!! }
};
$.fn.tooltip = function( method ) {
// Method calling logic
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
};
})( jQuery ); $('div').tooltip({ // calls the init method
foo : 'bar'
});
$('div').tooltip('hide'); // calls the hide method
$('div').tooltip('update', 'This is the new tooltip content!'); // calls the update method

jQuery自己的扩展也是使用这种插件结构。

b,事件

绑定事件的命名空间是比较不为人知的。如果你的插件绑定了某个事件,最好将它搞到一个命名空间中。这样,如果你以后需要解绑,就不会影响到其他绑定到这个事件上的函数了。你可以使用"."来增加命名空间。

 (function( $ ){
var methods = {
init : function( options ) {
return this.each(function(){
$(window).bind('resize.tooltip', methods.reposition);
});
},
destroy : function( ) {
return this.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 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
}; })( jQuery );
$('#fun').tooltip();
// Some time later...
$('#fun').tooltip('destroy');

在这个例子中,tooltip在init方法中初始化,它将reposition方法绑定到window对象的resize事件的tooltip名字空间下。稍候,如果开发者需要去掉这个tooltip,我们可以解绑这个绑定。这样就不会影响到其他绑定到window对象的resize事件的方法了。

c,数据

在开发插件的时候,你通常会有保持状态或者检查你的插件是否已经初始化的需要。使用jQuery的data方法是保持变量的很好的方法。但是,我们不把变量单独保存,而是放在一个对象中,这样就可以在一个名字空间下统一访问了。

 (function( $ ){
var methods = {
init : function( options ) {
return this.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( ) {
return this.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 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
}; })( jQuery );

使用data方法可以帮助你在插件的各个方法间保持变量和状态。将各种变量放在一个对象中,可以方便访问,也可以方便移除。

7,总结与最佳实践

编写jQuery插件可以充分利用库,将公用的函数抽象出来,“循环利用”。以下是简短的总结:

● 使用(function($){//plugin})(jQuery);来包装你的插件

● 不要在插件的初始范围中重复包裹

● 除非你返回原始值,否则返回this指针来保证可链式

● 不要用一串参数,而是使用一个对象,并且设置默认值

● 一个插件,不要为jQuery.fn附上多个函数

● 为你的函数,事件,数据附着到某个命名空间

深入理解jQuery插件开发总结(二)的更多相关文章

  1. 深入理解jQuery插件开发总结(四)

    jQuery插件开发模式 软件开发过程中是需要一定的设计模式来指导开发的,有了模式,我们就能更好地组织我们的代码,并且从这些前人总结出来的模式中学到很多好的实践. 根据<jQuery高级编程&g ...

  2. 深入理解jQuery插件开发总结(一)

    由于这篇文章比较长,所以分了四个阶段讲,从简单的入门级到最后到综合级,有些列子和图片都是转载其他博主的,希望对想写插件对同学会有帮助.这里分享个好久之前写的一个jquery插件(网站的功能引导插件,思 ...

  3. 深入理解JQuery插件开发

    如果你看到这篇文章,我确信你毫无疑问会认为jQuery是一个使用简便的库.jQuery可能使用起来很简单,但是它仍然有一些奇怪的地方,对它基本功能和概念不熟悉的人可能会难以掌握.但是不用担心,我下面已 ...

  4. 深入理解jQuery插件开发(转)

    转自:http://blog.jobbole.com/30550/ 如果你看到这篇文章,我确信你毫无疑问会认为jQuery是一个使用简便的库.jQuery可能使用起来很简单,但是它仍然有一些奇怪的地方 ...

  5. [转]深入理解jQuery插件开发

    如果你看到这篇文章,我确信你毫无疑问会认为jQuery是一个使用简便的库.jQuery可能使用起来很简单,但是它仍然有一些奇怪的地方,对它基本功能和概念不熟悉的人可能会难以掌握.但是不用担心,我下面已 ...

  6. 深入理解jQuery插件开发(转)

    如果你看到这篇文章,我确信你毫无疑问会认为jQuery是一个使用简便的库.jQuery可能使用起来很简单,但是它仍然有一些奇怪的地方,对它基本功能和概念不熟悉的人可能会难以掌握.但是不用担心,我下面已 ...

  7. 深入理解jQuery插件开发总结(三)

    容器:一个即时执行函数 根本上来说,每个插件的代码是被包含在一个即时执行的函数当中,如下: (function(arg1, arg2) { // 代码 })(arg1, arg2); 即时执行函数,顾 ...

  8. 深入理解jQuery插件开发【转】

    如果你看到这篇文章,我确信你毫无疑问会认为jQuery是一个使用简便的库.jQuery可能使用起来很简单,但是它仍然有一些奇怪的地方,对它基本功能和概念不熟悉的人可能会难以掌握.但是不用担心,我下面已 ...

  9. jQuery插件开发的模式和结构

    jQuery插件开发 一般来说,jQuery插件的开发分为两种:一种是挂在jQuery命名空间下的全局函数,也可称为静态方法:另一种是jQuery对象级别的方法,即挂在jQuery原型下的方法,这样通 ...

随机推荐

  1. short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?

    对于 short s1 = 1; s1 = s1 + 1;由于 s1+1运算时会自动提升表达式的类型,所以结果是 int型,再赋值给 short 类型 s1时, 编译器将报告需要强制转换类型的错误.对 ...

  2. Windows下Jmeter安装出现Not able to find Java executable or version问题解决方案

    安装好java1.8.jmeter4.0,并java -version正常,jmeter也能正常使用.某一次使用突然出现Not able to find Java executable or vers ...

  3. c 调用 lua 向lua函数 传递table

    参考 https://www.myvoipapp.com/blogs/yxh/2016/07/14/c%E5%90%91lua%E5%87%BD%E6%95%B0%E4%BC%A0%E9%80%92t ...

  4. BZOJ1721 Ski Lift 缆车支柱

    Description Farmer Ron in Colorado is building a ski resort for his cows (though budget constraints ...

  5. 榨取kkksc03 多维dp

    榨取kkksc03 多维dp 题面:洛谷 P1855 榨取kkksc03 一道简单的动态规划,背包再加一维费用,首先可以易得三维动态规划转移方程 \[ dp[i][j][w]=\left\{ \beg ...

  6. [转] Linux中的默认权限与隐藏权限(文件、目录)

    [From] https://blog.csdn.net/davidsky11/article/details/25424615 一个文件(或目录)拥有若干个属性,包括(r/w/x)等基本属性,以及是 ...

  7. 单臂vlan路由实现过程

    单臂路由拓扑图如下: 实现步骤如下: 1)pc的ip自己配置. 2)在交换机的各个端上划分好vlan 下联口:vlan 10     port g1/0/2 vlan 20   port g1/0/3 ...

  8. BFS - 20190206

    1.二叉树 BFS 2.拓扑排序  重点 BFS 3.棋盘上的宽搜  BFS 图的遍历 层级遍历,由点及面,拓扑排序,简单图的最短路径 如果题目问最短路径:可能是BFS或者DP, 最长路径:DFS q ...

  9. Hangfire项目

    什么是Hangfire Hangfire 是一个开源的.NET任务调度框架,目前1.6+版本已支持.NET Core.个人认为它最大特点在于内置提供集成化的控制台,方便后台查看及监控: 另外,Hang ...

  10. es第十篇:Elasticsearch for Apache Hadoop

    es for apache hadoop(elasticsearch-hadoop.jar)允许hadoop作业(mapreduce.hive.pig.cascading.spark)与es交互. A ...