「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
});
相關文章
相關標籤/搜索