jQuery是目前最流行的JavaScript轻量库。
jQuery好用在哪里:封装了多种操作dom的方法、支持链式操作、兼容性好。
但是jQuery内置的方法不可能满足用户的所有需求,要实现自定义方法可以扩展jQuery。
(一)编写jQuery Plugin(插件)
给jQuery对象$.fn扩展一个新方法:
jQuery.fn = $.fn = jQuery.prototype // jQuery 的对象原型
eg1. 扩展一个显示高亮的方法highlight()
$.fn.highlight = function () {
// this已绑定为当前jQuery对象:
this.css('backgroundColor', '#fffceb').css('color', '#d85030');
return this;
}
// 调用
$("#text").highlight();
注意:最后返回了return this; 这是为什么?因为jQuery对象支持链式操作,我们自己写的扩展方法也需要满足此要求。
eg2. 自己设定高亮的颜色,传递设置参数options
$.fn.highlight = function (options) {
// 要考虑到各种情况:
// options为undefined
// options只有部分key
var bgcolor = options && options.backgroundColor || '#fffceb';
var color = options && options.color || '#d85030';
this.css('backgroundColor', bgcolor).css('color', color);
return this;
}
// 调用
$("#text").highlight({
backgroundColor: '#00a8e6',
color: '#ffffff'
});
注意:options对象使用了&&和||短路操作符,总能得到一个有效值。
(二)extend()方法
jQuery为开发插件提供了extend()方法。extend 方法挂载在 jQuery 和 jQuery.fn 两个不同的对象上:
(1)jQuery.extend() = $.extend()
// 扩展类方法 ,不需要实例化就可以使用的方法(工具类)。调用:$.fun(); 或 jQuery.fun();
(2)jQuery.fn.extend() = $.fn.extend()
// 扩展实例方法 , 通过实例(如$("selector"))调用。调用:$("selector").fun();
1、$.extend()用于合并对象
对于上面eg2中的highlight()函数,可以使用
jQuery.extend(target [, object1] [, objectN])
方法,合并 object1 ... objectN 到 target 对象。遇到同名属性,则使用靠后的对象的值。
eg3. 使用$.extend()方法,修改highlight()的传参方式
$.fn.highlight = function (options) {
// 把默认值和用户传入的options合并到对象{}中并返回:
var opts = $.extend({}, {
backgroundColor: '#00a8e6',
color: '#ffffff'
}, options);
this.css('backgroundColor', opts.bgcolor).css('color', opts.color);
return this;
}
// 调用
$("#text").highlight();
上述写法仍然存在问题,如果用户不想使用opts中的默认值,想自己设定默认值,需要进一步修改。
eg4. 允许修改默认值,最终版highlight()方法
$.fn.highlight = function (options) {
// 合并默认值和用户设定值:
var opts = $.extend({}, $.fn.highlight.defaults, options);
this.css('backgroundColor', opts.backgroundColor).css('color', opts.color);
return this;
}
// 设定默认值:
$.fn.highlight.defaults = {
color: '#d85030',
backgroundColor: '#fff8de'
}
// 调用
$("#text").highlight();
此时,用户可一次性设定默认值,简单调用highlight()就可以了。
2、$.extend()用于扩展工具类方法
eg. 为jQuery类添加min()和max()方法
$.extend({
/* 返回两个元素中较小的值 */
min: function(a, b) {
return a < b ? a : b;
},
/* 返回两个元素中较大的值 */
max: function(a, b) {
return a > b ? a : b;
}
});
// 调用
$.min(2, 3); // 2
$.max(4, 5); // 5
3. $.fn.extend() 方法
为jQuery实例对象添加方法,必须创建了实例才可以调用。比如:使用id选择器创建的实例$("#btn")。
eg. $.fn.extend()重写highlight()方法
$.fn.extend({
highlight: function(options) {
// 合并默认值和用户设定值:
var opts = $.extend({}, $.fn.highlight.defaults, options);
this.css('backgroundColor', opts.backgroundColor).css('color', opts.color);
return this;
}
});
// 设定默认值
$.fn.highlight.defaults.color = '#659f13';
$.fn.highlight.defaults.backgroundColor = '#f2fae3';
// 调用
$("#text").highlight();
(三)针对特定元素的扩展
Query对象的一些方法只能作用在特定DOM元素上,比如submit()方法只能针对form。
如果我们编写的扩展只能针对某些类型的DOM元素,应该怎么写?
方法:我们可以借助filter()方法来过滤,从而实现针对特定元素的扩展。
eg. 给所有的超链接加上跳转提示
$.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(' <i class="uk-icon-external-link"></i>')
.click(function () {
if(confirm('你确定要前往' + url + '?')) {
window.open(url);
}
});
}
});
}
// 调用
$("#alink").external();
(四)总结
最后,总结出编写一个jQuery插件的原则:
- 通过 $.fn.extend()方法,给 $.fn 绑定自定义函数,实现插件的代码逻辑;
- 插件函数最后要 return this,以支持链式调用;
- 插件函数可设定默认值,绑定在$.fn.<pluginName>.defaults 上;
- 除了默认设定值,插件函数可传入用户配置options,保证用户在调用时可传入设定值以便覆盖默认值。