有时候,你希望有一块功能在整个代码当中都可以使用。例如,你可能想要有一个单一的方法可以在jQuery选择器上进行调用,用于处理该选择器上的一系列操作。又或许你编写了一个十分有用的工具函数,并希望能够简单的迁移到其它的项目当中。在这种情况下,你也许想要编写一个插件。

jQuery工作原理101:jQuery对象方法和工具方法

在我们编写插件前,首先需要对jQuery的工作原理有一些了解。看一下这段代码:

 $( "a" ).css( "color", "red" );

这是一段相当基础的jQuery代码,但你知道在幕后都发生了什么吗?每当你使用那个 $ 方法选择一个元素时,它返回一个jQuery对象。该对象包含了所有你已经用过的方法(.css(), .click(), etc.)以及所有与选择器相符的元素。jQuery对象从 $.fn 对象获得这些方法。该对象包含了所有jQuery对象的方法,并且如果我们想要编写自己的方法,它也会同样包含这些方法。

此外,jQuery工具方法 $.trim() 被用来将用户输入内容中的任意前置或后置空白字符移除。工具方法是指那些直接驻留在 $ 方法自身的方法。当你所扩展的jQuery API不需要对你所取回的DOM元素进行操作时,你或许就会想要编写一个工具方法插件。

(原文说的大意是上面使用到了$.trim() 方法,然后对其进行一下说明,可是上面哪有什么 $.trim(),因此只好这么翻了。)

基本插件编写

比如说我们想要创建一个插件,用于将一组取回元素中的文本变成绿色。我们所需要做的就是添加一个名为 greenify 的方法到 $.fn 当中,之后你将可以像使用其他jQuery对象方法那样使用它。

 $.fn.greenify = function() {
this.css( "color", "green" );
}; $( "a" ).greenify(); // Makes all the links green.

要注意的是,在使用另一个方法 .css() 时,我们使用了 this 而不是 $(this) 。这是因为我们的 greenify 方法和 .css() 同属于一个对象。

连缀

插件已经可以使用了,但是想要让我们的插件真正用于实战,还有几件事情需要我们来完成。连缀是jQuery的特性之一,它使你可以在一个选择器上连接五个或是更多的操作。这些都是通过将所有的jQuery对象方法再次返回到原始的jQuery对象来实现的(但也有一些例外:调用不带参数的 .width() 方法将返回被选中元素的宽度,并且它是无法进行连缀的)。下面使用一行代码使我们的插件方法可以进行连缀:

 $.fn.greenify = function() {
this.css( "color", "green" );
return this;
} $( "a" ).greenify().addClass( "greenified" );

注意,连缀的概念并不适用于jQuery工具方法,例如:$.trim()。

保护 $Alias 并添加作用域

在JavaScript类库当中, $ 变量十分的流行,如果你在使用jQuery的同时又使用其它的类库,你或许将不得不使用 jQuery.noConflict() 方法来使jQuery不再使用 $ 变量。然而,这将会打乱我们的插件,因为它是在假定 $ 是jQuery的别名的情况下编写的。为了可以兼容其它的插件,并且仍旧使用jQuery的 $ 别名,我们需要将所有的代码放置在立即调用的函数表达式(Immediately Invoked Function Expression)当中,然后传递jQuery函数,并将 $ 作为参数:

 (function ( $ ) {

     $.fn.greenify = function() {
this.css( "color", "green" );
return this;
}; $.ltrim = function( str ) {
return str.replace( /^\s+/, "" );
}; $.rtrim = function( str ) {
return str.replace( /\s+$/, "" );
}; }( jQuery ));

此外,立即调用的函数表达式的主要作用是允许我们拥有自己的私有变量。假设我们需要不同的绿色,并且想要把它存储到一个变量当中。

 (function ( $ ) {

     var shade = "#556b2f";

     $.fn.greenify = function() {
this.css( "color", shade );
return this;
}; }( jQuery ));

最小化插件足迹

当编写插件时,最佳的实践是只占用一个 $.fn 扩展槽。这会降低插件被覆盖的几率,同时也会降低覆盖其它插件的几率。换句话说,下面的做法是不恰当的:

 (function( $ ) {

     $.fn.openPopup = function() {
// Open popup code.
}; $.fn.closePopup = function() {
// Close popup code.
}; }( jQuery ));

更为合理的做法应当是只使用一个扩展槽,使用参数来控制扩展槽进行什么操作。

 (function( $ ) {

     $.fn.popup = function( action ) {

         if ( action === "open") {
// Open popup code.
} if ( action === "close" ) {
// Close popup code.
} }; }( jQuery ));

使用 each() 方法

标准的jQuery对象将包含对任意数量DOM元素的引用,这就是为什么jQuery对象通常被当成集合。如果你想对具体的元素集进行任意操作(例如,得到一个data属性,计算具体的属性等)此时你就需要使用 .each() 方法来遍历元素集。

 $.fn.myNewPlugin = function() {

     return this.each(function() {
// Do something to each element here.
}); };

需要注意的是,我们返回 .each() 方法的结果而非返回 this 。因为 .each() 方法是可连缀的,它将返回 this ,和我们直接返回 this 是一样的。这是目前为止我们进行的保持连缀的最佳做法。

接受选项

当插件变得越来越复杂时,让插件可以通过选项进行自定义是一个不错的想法。尤其是当选项数量较多时,最简单的方式是使用对象字面量(object literal)。让我们对插件进行一些修改,使其能够接受一些选项。

 (function ( $ ) {

     $.fn.greenify = function( options ) {

         // This is the easiest way to have default options.
var settings = $.extend({
// These are the defaults.
color: "#556b2f",
backgroundColor: "white"
}, options ); // Greenify the collection based on the settings variable.
return this.css({
color: settings.color,
backgroundColor: settings.backgroundColor
}); }; }( jQuery ));

使用范例:

 $( "div" ).greenify({
color: "orange"
});

color 的默认值 #556b2f 通过 $.extend() 方法被进行了覆盖,从而变成了橙色。

完整实现

下面是一个小插件的范例,它使用了我们之前所讨论的一些技巧:

 (function( $ ) {

     $.fn.showLinkLocation = function() {

         return this.filter( "a" ).each(function() {
$( this ).append( " (" + $( this ).attr( "href" ) + ")" );
}); }; }( jQuery )); // Usage example:
$( "a" ).showLinkLocation();

这个便利的插件将遍历集合中的所有锚点,然后将 href 属性附加到括号当中。

 <!-- Before plugin is called: -->
<a href="page.html">Foo</a> <!-- After plugin is called: -->
<a href="page.html">Foo (page.html)</a>

该插件还可以进行如下的优化:

 (function( $ ) {

     $.fn.showLinkLocation = function() {

         return this.filter( "a" ).append(function() {
return " (" + this.href + ")";
}); }; }( jQuery ));

我们将使用 .append() 方法的特性来接受一个回调函数,并且该回调函数的返回值取决于集合中的每个元素各自所附加的内容。要注意的是,与此同时同时我们并没有使用 .attr() 方法来取得 href 属性,因为原生的DOM API让我们可以轻松的访问已合理命名的 href 属性。

原文地址:http://learn.jquery.com/plugins/basic-plugin-creation/

jQuery 如何创建基本插件(翻译)的更多相关文章

  1. jQuery自定义滚动条样式插件mCustomScrollbar

    如果你构建一个很有特色和创意的网页,那么肯定希望定义网页中的滚动条样式,这方面的 jQuery 插件比较不错的,有两个:jScrollPane 和 mCustomScrollbar. 关于 jScro ...

  2. 强大的支持多文件上传的jQuery文件上传插件Uploadify

    支持多文件上传的jQuery文件上传插件Uploadify,目前此插件有两种版本即Flash版本和HTML5版本,对于HTML5版本会比较好的支持手机浏览器,避免苹果手机Safari浏览器不支持Fla ...

  3. jQuery文件上传插件Uploadify(转)

    一款基于flash的文件上传,有进度条和支持大文件上传,且可以多文件上传队列. 这款在flash的基础上增加了html5的支持,所以在移动端也可以使用. 由于官方提供的版本是flash免费,html5 ...

  4. jQuery打造智能提示插件二(可编辑下拉框)

    在上一篇 jQuery打造智能提示插件 上改进,增加下拉按钮,修复点击下拉区域外不隐藏BUG 效果 下拉按钮素材: js封装,注意红色部分为BUG修复,然后传入boxwidth不带px: /* /// ...

  5. 12款经典的白富美型—jquery图片轮播插件—前端开发必备

    图片轮播是网站中的常用功能,用于在有限的网页空间内展示一组产品图片或者照片,同时还有非常吸引人的动画效果.本文向大家推荐12款实用的 jQuery 图片轮播效果插件,帮助你在你的项目中加入一些效果精美 ...

  6. jQuery文件上传插件jQuery Upload File 有上传进度条

    jQuery文件上传插件jQuery Upload File 有上传进度条 jQuery文件上传插件jQuery Upload File,插件使用简单,支持单文件和多文件上传,支持文件拖拽上传,有进度 ...

  7. 【jquery】Validform,一款不错的 jquery 表单验证插件

    关于 Validform 这是一款很不错的 jquery 表单验证插件,它几乎能够满足任何验证需求,仅仅一行代码就能搞定整站的表单验证. $('form').Validform(); 为什么能如此方便 ...

  8. 【jQuery基础学习】06 jQuery表单验证插件-Validation

    jQuery的基础部分前面都讲完了,那么就看插件了. 关于jQuery表单验证插件-Validation validation特点: 内置验证规则:拥有必填.数字.E-Mail.URL和信用卡号码等1 ...

  9. jQuery extend() & jQuery.fn.extend(),插件编写

    资料来源:网上资料整理并自行改编测试.复制以下代码并依赖jquery.js,jquery.validate.js即可执行.有误之处,请@我啊,敬请赐教. <!DOCTYPE html PUBLI ...

随机推荐

  1. nginx第三方模块---nginx-sticky-module的使用(基于cookie的会话保持)

    目前的项目网站架构中使用了F5和nginx,F5用来做负载均衡,nginx只用作反向代理服务器.最近应客户的要求准备去掉F5,使用软负载.大家都知道nginx抗并发能力强,又可以做负载均衡,而且使用n ...

  2. Codeforces 715A & 716C Plus and Square Root【数学规律】 (Codeforces Round #372 (Div. 2))

    C. Plus and Square Root time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  3. Contains Duplicate II ——LeetCode

    Given an array of integers and an integer k, find out whether there there are two distinct indices i ...

  4. Shader Forge 刀光溶解

    实际特效时,时间可以控制vertex color.a,shader forge 还只是玩具,试验用具,离商业产品质量还有差距. 其实,有技术美术的画,很多问题,美术能自己解决,都是一些欠缺通道的问题, ...

  5. FATE(完全背包)

    /* http://acm.hdu.edu.cn/showproblem.php?pid=2159 分析: 和普通的完全背包没有什么太大的区别 但是题目中给出了限制最多可杀s个怪 用二维数组dp[i] ...

  6. Websphere内存溢出的日志

    项目中碰到Websphere内存溢出的情况.原因可能:出现过多内存泄漏,或者分配过多大内存等.解决方法:1.进入was管理控制台,选择 应用程序服务器 > server1 > 进程定义 & ...

  7. angularJS 过滤器 表单验证

    过滤器1.filter的作用就是接收一个输入,通过某个规则进行处理,然后返回处理后的结果,主要用于数据的格式化.2.内置过滤器(1)Currency(货币)将一个数值格式化为货币格式,默认为$(2)D ...

  8. 总结的一些封装好的javascript函数

    平时总结的一些常用javascript函数封装: //获取样式 function getStyle(obj,name){ if(obj.currentStyle){ return obj.curren ...

  9. 软件设计模式 B卷

            软件设计模式 试 卷(作业考核 线上)  B  卷   学习中心:            院校学号:             姓名                (共        页 ...

  10. Java同步工具类总结

    先谈谈闭锁和栅栏的区别: 1.关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行. 2.闭锁用于等待某一个事件的发生,举例:CountDownLatch中await方法等待计数器为零时,所有事件 ...