jQuery插件 - 编写基本插件

来源:互联网 发布:系统数据架构设计 编辑:程序博客网 时间:2024/05/08 16:35

如何创建一款基本的插件

有时候你想让一部分功能贯穿你的代码皆可使用。例如,或许你想要一个方法能够在调用一个jQuery选择器后执行一系列的操作。或许你编写了一个非常有用的工具函数想要方便地移植到其他项目中。在这些情况下,你可能考虑要编写一款插件。

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

在我们编写自己的jQuery插件之前,有必要首先对jQuery的工作原理稍作了解。请看如下代码:
$( "a" ).css( "color", "red" );
这是一段优美的jQuery代码,但是你了解这幕后的工作么?每当你使用$函数选择HTML元素的时候,都会返回一个jQuery对象。这个对象包含你使用过的所有方法(.css(),.click(), 等等)以及所有符合选择器要求的HTML元素。该返回的jQuery对象从$.fn对象获得这些方法,它也包含jQuery的所有方法。如果我们想要编写自己的方法,也将需要包含这些。

此外jQuery工具函数$.trim用来除去用户输入中包含的首尾空格字符。工具方法是插在$函数内部的方法(注:静态方法)。如果你的jQuery API拓展插件与遍历的DOM元素无关,你或许应该考虑编写一款工具方法插件。
基本插件制作

比如说我们想制作一款可以让指定元素内部的文本变成绿色的插件。我们所需要做的仅仅是为$.fn对象添加一个名为greenify的方法,然后它便会像其他jQuery对象方法一样生效。
$.fn.greenify = function() {    this.css( "color", "green" );};$( "a" ).greenify(); // 将所有的链接变为绿色。

链式操作

它成功了,但要是想让插件变得更加实用我们还需要做一些完善工作。jQuery的特性之一是链式操作,当你对一个选择器执行5、6个连续动作,这是通过让jQuery对象的方法返回一个jQuery对象本身来完成这一操作(也有一些例外:调用无参函数.width()返回的是选中对象的宽度值,所以这种情况是不可链的)。

想让我们的插件支持链式操作只需要加入如下一样代码:
$.fn.greenify = function() {    this.css( "color", "green" );    return this;}$( "a" ).greenify().addClass( "greenified" );
注意链式操作的概念对jQuery工具函数例如$.trim()并不适用。

保护$别名以及添加命名空间

$变量在jQuery库中十分常见,如果你在使用jQuery库的同时使用了其他库,那么你需要执行jQuery.noConflict()来解除jQuery对$变量的控制权。然而这么做会破坏我们的插件因为我们起初便假设$是jQuery的一个别名。为了避免和别的插件的冲突,并且能够继续使用jQuery的$别名,我们只需要把所有代码都放进一个立即调用函数内部,定义函数的形参为$,并把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() {        // 弹出对话框代码    };    $.fn.closePopup = function() {        // 关闭对话框代码    };}( jQuery ));
只占用一个接口的方式更佳,并可以使用参数来控制接口的行为。
(function( $ ) {    $.fn.popup = function( action ) {        if ( action == "open" ) {            // 弹出对话框代码        }        if( action == "close" ) {            // 关闭对话框代码        }    };}( jQuery ));

使用each()方法

你构造的jQuery对象一般会包含对任意数量的DOM元素的引用,这便可以解释为什么jQuery对象一般被引用为一个集合。如果你想针对特定的元素进行操作(例如获取data属性,计算特定元素的位置)那么你需要调用.each()方法来遍历所有元素
$.fn.myNewPlugin = function() {     return this.each(function() {        // 对每个元素做点什么    }); };
请注意以上返回的是.each()的返回值而非返回this指针。既然.each()已经是可链的,所以它会返回this指针,然后被我们继续返回到上层。这是我们目前维持链式操作较好的方式。

接受参数

随着你的插件变得越来越复杂,十分推荐让你的插件接受参数以使之更加可定制化。践行此法最简单的方式是,尤其是当参数数量过多的时候,使用对象字面量。让我们对我们的greenify插件稍作修改使之能够接受参数。
(function ( $ ) {     $.fn.greenify = function( options ) {         // 使用默认参数的最间方法        var settings = $.extend({            // 此处是默认参数            color: "#556b2f",            backgroundColor: "white"        }, options );         // 根据settings变量的值对选定的元素集合执行操作        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 )); // 使用范例:$( "a" ).showLinkLocation();
这个方便的插件可以遍历所有的超链接并在超链接的尖括号内部追加该链接的href属性值。
<!-- 插件调用前 --><a href="page.html">某某</a><!-- 插件调用后 --><a href="page.html">某某 (page.html)</a>
我们的插件可以被进一步优化:
(function( $ ) {     $.fn.showLinkLocation = function() {         return this.filter( "a" ).append(function() {            return " (" + this.href + ")";        });     }; }( jQuery ));
我们让.append()方法接受一个回调函数作为参数。注意我们没有使用.attr()方法来获取href属性,因为原生的DOM API提供了更直接的获取href属性的方式。
原创粉丝点击