「jQuery插件开发日记」(一)如何创建一个基础的插件 - [翻译]

_How to Create a Basic Plugin_, 翻译自 jQuery 官方网站。javascript

如何创建一个基础的插件

有时,你想要在你的代码里面实现一个可复用的功能。
举个例子,若是你想要在一个 jQuery 对象上调用一个简单的方法,来对这个对象进行一系列的操做,那么你应该写一个 jQuery 插件。css

jQuery是如何工做的

在开始写插件以前,咱们必须对 jQuery 的工做方式有些许的认识。来看下面的代码:html

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

这是一句很是基础的 jQuery 代码,可是你知道它背后发生了什么吗?当你使用 $ 去选择元素的时候,它就会返回一个 jQuery 对象。这个对象包含可用的全部方法(.css(), .click()等)和全部符合你传入选择器的元素。java

这个对象从 $.fn 对象继承全部的方法。 $.fn 对象包括全部 jQuery 对象的方法,也就是说,若是你想添加本身的方法的话,你须要将方法添加到 $.fn 对象上。jquery

※ 译者注 ※
$.fn == $.prototype // trueapp

创建一个基础的插件

假设咱们如今要创建一个让元素里的文字变绿的插件。
咱们须要作的只是在 $.fn 里添加一个方法 greenify函数

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

注意到咱们在这段代码里面用的是 this 而不是 $(this)。这是由于在 greenify 函数中,this 指代的是 jQuery 对象,因此可使用 jQuery 的全部方法。网站

链式操做

jQuery 最大的特色之一就是支持链式操做。链式操做的实现是靠 jQuery 全部的方法返回 jQuery 对象来实现的(也有一些例外,好比无参数的 .width() 返回的就是宽度)。this

只须要增长一行代码,咱们就可让咱们的插件变得能够链式操做:prototype

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

命名空间

$ 这个变量在不少 JavaScript 库里都很受欢迎。若是你一块儿使用 jQuery 和其余的库,你可能就得用 jQuery.noConflict() 来让 jQuery 返还对 $ 变量的控制权了。

然而因为 $ 变量已经不是 jQuery 了,咱们的插件就没办法工做了。要让咱们的插件继续工做,而且也能够和其余的库一块儿使用,咱们须要将咱们的代码放入一个即时执行函数表达式中,而后将jQuery当作参数传入,命名为 $

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

除了上面提到的两个功能,即时执行函数增长了一层做用域,让咱们能够定义本身的私有变量。例如:

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

※ 译者注 ※
jQuery.noConflict() 的做用是返还 $ 的控制权。

为何说是返还呢?由于 jQuery 在初始化的时候,会记录$ 这个变量,而后再将 $ 绑定为自身。
因此调用 jQuery.noConflict(),其实是将 $ 赋值为以前记录的旧值。

减小绑定方法的数量

当编写插件时,咱们最好只在 $.fn 上绑定一个方法。这不只减小了其余的插件覆盖你的插件的概率,也减小了你的插件覆盖其余插件的概率。

使用 each() 方法

通常来讲,使用选择器选择的 jQuery 对象都是一个集合。若是你想对这里的某些元素进行操做(好比获取属性,计算位置等),你就须要用到 .each() 方法来进行遍历。

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

※ 译者注 ※
有读者可能会问,在以前的代码中 .css() 并无进行遍历,如何使全部元素里的问题都变成绿色?
这是由于 .css() 方法里已经作了这个遍历的工做了。

注意到咱们返回的是 .each() 的结果,而不是 this。这是由于 .each() 也是可链式操做的, 它返回的也是 this。不过这样写更加契合链式操做的思想。

接受用户配置

当你的插件变得愈来愈复杂的时候,你最好经过接受用户的配置来让用户定制某些功能。

最简单的方法就是使用一个对象来储存配置。

(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 ));

/* Example usage */
$( "div" ).greenify({
    color: "orange"
});

默认的颜色值 #556b2f 被用户定义的值 orange 覆盖。

※ 译者注 ※
x.extend([deep], target [,obj1][,objN])

.extend() 方法主要是将全部 obj 的属性和方法所有添加到 target 上。同名的会覆盖,而 nullundefined 会被忽略。
当只有一个参数的时候,x 就变成了 target,也就是将这个惟一的参数的全部方法和属性所有添加到 x 中。

x 能够是:

  • $

  • $.fn

$.extend()$.fn.extend() 的不一样也就很是明显了。

完整的例子

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

HTML 结构:

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

※ 译者注 ※
上面的例子里, this.filter()this.hrefthis 是不一样的。前者是 jQuery 对象,后者是 HTMLElement 对象。

var $links = $('a');

$links[0] instanceof HTMLElement; // true
$links.slice(0, 1) instanceof jQuery; // true
$links.each(function(){
    this instanceof HTMLElement; // true
});
相关文章
相关标签/搜索