什么是jQuery插件?
扩展jQuery原型对象的一个方法(jQuery插件是jQuery对象的一个方法)
jQuery插件的使用方式就是jQuery对象方法的调用。
jQuery.fn=jQuery.prototype
使用(jQuery插件如何使用?)
jQuery.fn.myPlugin = function() {
// 插件的具体内容放在这里
};
$的冲突
把 jQuery 传递给 IIFE(立即调用函数),并通过它映射成 $ ,这样就避免了在执行的作用域里被其它库所覆盖。
(function( $ ) {
$.fn.myPlugin = function() {
// 插件的具体内容放在这里
};
})( jQuery );
加分号的意义:
以 “(”、“[”、“/”、“+”、或 “-” 开始,那么它极有可能和前一条语句合在一起解释。
------《JavaScript 权威指南》
避免js代码压缩时出错
上下文中的this指向
在插件函数的立即作用域中,关键字 this 指向调用插件的 jQuery 对象。
(function( $ ){
$.fn.myPlugin = function() {
// 没有必要再作 $(this) ,因为"this"已经是 jQuery 对象了
// $(this) 与 $($('#element')) 是相同的
this.fadeIn('normal', function(){
// 在这里 this 关键字指向 DOM 元素
});
};
})( jQuery );
$('#element').myPlugin();
一个例子
(function( $ ){
$.fn.maxHeight = function() {
var max = 0;
this.each(function() {
max = Math.max( max, $(this).height() );
});
return max;
};
})( jQuery );
var tallest = $('div').maxHeight(); // 返回最高 div 的高度
链式调用
在扩展函数的最后return 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');
默认参数设置
除了
$.extend()
、也可以&&
或||
短路操作符
$.extend(target, obj1, obj2, ...)
,它把多个object对象的属性合并到第一个target对象中,遇到同名属性,总是使用靠后的对象的值,也就是越往后优先级越高。
(function( $ ){
$.fn.tooltip = function( options ) {
//默认参数可以写在外面
var settings = $.extend( {
'location' : 'top',
'background-color' : 'blue'
}, options);
return this.each(function() {
});
};
})( jQuery );
$('div').tooltip({
'location' : 'left'
});
$.fn 名称空间
(function( $ ){
var methods = {
init : function( options ) {
// 这
},
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 );
// 调用 init 方法
$('div').tooltip();
// 调用 init 方法
$('div').tooltip({
foo : 'bar'
});
// 调用 hide 方法
$('div').tooltip('hide');
// 调用 update 方法
$('div').tooltip('update', 'This is the new tooltip content!');
事件,bind、unbind
bind方法支持为绑定事件定义名称空间。unbind的时候就不会影响到相同事件类型上的其它已绑定事件。
(function( $ ){
var methods = {
init : function( options ) {
return this.each(function(){
//把 reposition 方法绑定到 window 对象的 resize 事件上,名称空间为 "tooltip"。
$(window).bind('resize.tooltip', methods.reposition);
});
},
destroy : function( ) {
return this.each(function(){
//如果开发者想要销毁对象,可以把插件的名称空间(即 "tooltip")传给 unbind 方法,以便解除本插件对所有事件的绑定。
//可以安全的地解除本插件的事件绑定,避免意外影响插件之外绑定的事件。
$(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');
最佳实践
- 总是把插件包装在闭包中 { /* plugin goes here */ })( jQuery )。
- 不在插件函数的立即作用域中额外包装 this 关键字。
- 总是让插件函数返回 this 关键字以保持 chainability ,除非插件有真正的返回值。
- 不要传给插件大量参数,应该传一个可以覆盖插件默认选项的设置对象。
- 在单个插件中,不要让一个以上的名称空间搞乱了 jQuery.fn 对象。
- 总是为方法、事件和数据定义名称空间。
其它 $.fn.extend
(function($){
$.fn.extend({
changeStyle: function(option){
var defaultSetting = { colorStr:"green",fontSize:12};
var setting = $.extend(defaultSetting,option);
this.css("color",setting.colorStr).css("fontSize",setting.fontSize+"px");
return this;
}
});
}(jQuery));
$.extend方法和$.fn.extend方法都可以用来扩展jQuery功能,通过阅读jQuery源码我们可以发现这两个方法的本质区别,那就是$.extend方法是在jQuery全局对象上扩展方法,$.fn.extend方法是在$选择符选择的jQuery对象上扩展方法。所以扩展jQuery的公共方法一般用$.extend方法,定义插件一般用$.fn.extend方法。
jQuery插件集
针对特定元素的扩展filter
$.fn.external = function () {
// return返回的each()返回结果,支持链式调用:
return this.filter('a').each(function () {
// 注意: each()内部的回调函数的this绑定为DOM本身!
var a = $(this);
var url = a.attr('href');
if (url && (url.indexOf('http://')===0 || url.indexOf('https://')===0)) {
a.attr('href', '#0')
.removeAttr('target')
.append(' ')
.click(function () {
if(confirm('你确定要前往' + url + '?')) {
window.open(url);
}
});
}
});
}
$('#main').external();
$('#main a').external();
jQuery.extend({...});静态方法
typeof jQuery
==>"function"
jQuery.fn.extend({...});jQuery原型上的方法
jQuery.fn=jQuery.prototype
jQuery.extend({...})是给function jQuery添加静态属性或方法
jQuery().extend({...})是给jQuery对象添加属性或方法
额外:
扩展类方法:
jQuery.extend({
fn1: function(){console.log('gyh')}
});
$.fn1(); // gyh
或者:
jQuery.fn2 = function(){console.log('gyh2')}
$.fn2();// gyh2
扩展实例方法(原型上的方法)
jQuery.fn.extend({
fn1: function(){console.log(this)}
});
$('body').fn1(); // [body.library.Chrome, prevObject: init(1), context: document, selector: "body"]
或者:
jQuery.fn.fn2 = function(){console.log(this)}
$('head').fn2(); // [head, prevObject: init(1), context: document, selector: "head"]