教你開發(fā)jQuery插件(常規(guī)寫法)

原文鏈接:http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html
要說jQuery 最成功的地方,我認為是它的可擴展性吸引了眾多開發(fā)者為其開發(fā)插件鸠澈,從而建立起了一個生態(tài)系統(tǒng)泻骤。這好比大公司們爭相做平臺一樣睦袖,得平臺者得天下葵第。蘋果,微軟纪岁,谷歌等巨頭,都有各自的平臺及生態(tài)圈则果。

學(xué)會使用jQuery并不難幔翰,因為它簡單易學(xué),并且相信你接觸jQuery后肯定也使用或熟悉了不少其插件短条。如果要將能力上升一個臺階导匣,編寫一個屬于自己的插件是個不錯的選擇。

本教程可能不是最精品的茸时,但一定是最細致的贡定。

jQuery插件開發(fā)模式

軟件開發(fā)過程中是需要一定的設(shè)計模式來指導(dǎo)開發(fā)的,有了模式可都,我們就能更好地組織我們的代碼缓待,并且從這些前人總結(jié)出來的模式中學(xué)到很多好的實踐。

根據(jù)《jQuery高級編程》的描述渠牲,jQuery插件開發(fā)方式主要有三種:
  1. 通過$.extend()來擴展jQuery
  2. 通過$.fn 向jQuery添加新的方法
  3. 通過$.widget()應(yīng)用jQuery UI的部件工廠方式創(chuàng)建

通常我們使用第二種方法來進行簡單插件開發(fā)旋炒,說簡單是相對于第三種方式。第三種方式是用來開發(fā)更高級jQuery部件的签杈,該模式開發(fā)出來的部件帶有很多jQuery內(nèi)建的特性瘫镇,比如插件的狀態(tài)信息自動保存鼎兽,各種關(guān)于插件的常用方法等,非常貼心铣除,這里不細說谚咬。

而第一種方式又太簡單,僅僅是在jQuery命名空間或者理解成jQuery身上添加了一個靜態(tài)方法而以尚粘。所以我們調(diào)用通過$.extend()添加的函數(shù)時直接通過$符號調(diào)用($.myfunction())而不需要選中DOM元素($('#example').myfunction())择卦。
請看下面的例子:

$.extend({
sayHello: function(name) {
    console.log('Hello,' + (name ? name : 'Dude') + '!');
}
})
$.sayHello(); //調(diào)用
$.sayHello('Wayou'); //帶參調(diào)用

運行結(jié)果:


image.png

上面代碼中,通過$.extend()向jQuery添加了一個sayHello函數(shù)郎嫁,然后通過$直接調(diào)用秉继。到此你可以認為我們已經(jīng)完成了一個簡單的jQuery插件了。

但如你所見泽铛,這種方式用來定義一些輔助方法是比較方便的尚辑。比如一個自定義的console,輸出特定格式的信息盔腔,定義一次后可以通過jQuery在程序中任何需要的地方調(diào)用它腌巾。

$.extend({
log: function(message) {
    var now = new Date(),
        y = now.getFullYear(),
        m = now.getMonth() + 1, //!JavaScript中月分是從0開始的
        d = now.getDate(),
        h = now.getHours(),
        min = now.getMinutes(),
        s = now.getSeconds(),
        time = y + '/' + m + '/' + d + ' ' + h + ':' + min + ':' + s;
    console.log(time + ' My App: ' + message);
}
})
$.log('initializing...'); //調(diào)用

運行結(jié)果:

image.png

但這種方式無法利用jQuery強大的選擇器帶來的便利铲觉,要處理DOM元素以及將插件更好地運用于所選擇的元素身上澈蝙,還是需要使用第二種開發(fā)方式。你所見到或使用的插件也大多是通過此種方式開發(fā)撵幽。

插件開發(fā)

下面我們就來看第二種方式的jQuery插件開發(fā)灯荧。

基本方法
先看一下它的基本格式:

$.fn.pluginName = function() {
//your code goes here
}

基本上就是往$.fn上面添加一個方法,名字是我們的插件名稱盐杂。然后我們的插件代碼在這個方法里面展開逗载。

比如我們將頁面上所有鏈接顏色轉(zhuǎn)成紅色,則可以這樣寫這個插件:

$.fn.myPlugin = function() {
//在這里面,this指的是用jQuery選中的元素
//example :$('a'),則this=$('a')
this.css('color', 'red');
}

在插件名字定義的這個函數(shù)內(nèi)部链烈,this指代的是我們在調(diào)用該插件時厉斟,用jQuery選擇器選中的元素,一般是一個jQuery類型的集合强衡。比如$('a')返回的是頁面上所有a標簽的集合擦秽,且這個集合已經(jīng)是jQuery包裝類型了,也就是說漩勤,在對其進行操作的時候可以直接調(diào)用jQuery的其他方法而不需要再用美元符號來包裝一下感挥。

所以在上面插件代碼中,我們在this身上調(diào)用jQuery的css()方法越败,也就相當于在調(diào)用 $('a').css()触幼。

理解this在這個地方的含義很重要。這樣你才知道為什么可以直接商用jQuery方法同時在其他地方this指代不同時我們又需要用jQuery重新包裝才能調(diào)用究飞,下面會講到置谦。初學(xué)容易被this的值整暈堂鲤,但理解了就不難。

現(xiàn)在就可以去頁面試試我們的代碼了媒峡,在頁面上放幾個鏈接筑累,調(diào)用插件后鏈接字體變成紅色。

<ul>
    <li><a >我的微博</a></li>
    <li><a href="http://http://www.cnblogs.com/Wayou/">我的博客</a></li>
    <li><a >我的小站</a></li>
</ul>
<p>這是p標簽不是a標簽丝蹭,我不會受影響</p>
<script src="jquery-1.11.0.min.js"></script>
<script src="jquery.myplugin.js"></script>
<script type="text/javascript">
    $(function(){
        $('a').myPlugin();
    })
</script>

運行結(jié)果:

image.png

下面進一步,在插件代碼里處理每個具體的元素坪蚁,而不是對一個集合進行處理奔穿,這樣我們就可以針對每個元素進行相應(yīng)操作。

我們已經(jīng)知道this指代jQuery選擇器返回的集合敏晤,那么通過調(diào)用jQuery的.each()方法就可以處理合集中的每個元素了贱田,但此刻要注意的是,在each方法內(nèi)部嘴脾,this指帶的是普通的DOM元素了男摧,如果需要調(diào)用jQuery的方法那就需要用$來重新包裝一下。

比如現(xiàn)在我們要在每個鏈接顯示鏈接的真實地址译打,首先通過each遍歷所有a標簽耗拓,然后獲取href屬性的值再加到鏈接文本后面。

更改后我們的插件代碼為:

$.fn.myPlugin = function() {
    //在這里面,this指的是用jQuery選中的元素
    this.css('color', 'red');
    this.each(function() {
        //對每個元素進行操作
        $(this).append(' ' + $(this).attr('href'));
    }))
}
調(diào)用代碼還是一樣的奏司,我們通過選中頁面所有的a標簽來調(diào)用這個插件

運行結(jié)果:

image.png

到此乔询,你已經(jīng)可以編寫功能簡單的jQuery插件了。是不是也沒那么難韵洋。

下面開始jQuery插件編寫中一個重要的部分竿刁,參數(shù)的接收。

支持鏈式調(diào)用

我們都知道jQuery一個時常優(yōu)雅的特性是支持鏈式調(diào)用搪缨,選擇好DOM元素后可以不斷地調(diào)用其他方法食拜。

要讓插件不打破這種鏈式調(diào)用,只需return一下即可副编。

$.fn.myPlugin = function() {
    //在這里面,this指的是用jQuery選中的元素
    this.css('color', 'red');
    return this.each(function() {
        //對每個元素進行操作
        $(this).append(' ' + $(this).attr('href'));
    }))
}

讓插件接收參數(shù)

一個強勁的插件是可以讓使用者隨意定制的负甸,這要求我們提供在編寫插件時就要考慮得全面些,盡量提供合適的參數(shù)痹届。

比如現(xiàn)在我們不想讓鏈接只變成紅色惑惶,我們讓插件的使用者自己定義顯示什么顏色,要做到這一點很方便短纵,只需要使用者在調(diào)用的時候傳入一個參數(shù)即可带污。同時我們在插件的代碼里面接收。另一方面香到,為了靈活鱼冀,使用者可以不傳遞參數(shù)报破,插件里面會給出參數(shù)的默認值。

在處理插件參數(shù)的接收上千绪,通常使用jQuery的extend方法充易,上面也提到過,但那是給extend方法傳遞單個對象的情況下荸型,這個對象會合并到j(luò)Query身上盹靴,所以我們就可以在jQuery身上調(diào)用新合并對象里包含的方法了,像上面的例子瑞妇。當給extend方法傳遞一個以上的參數(shù)時稿静,它會將所有參數(shù)對象合并到第一個里。同時辕狰,如果對象中有同名屬性時刑枝,合并的時候后面的會覆蓋前面的腻贰。

利用這一點辨绊,我們可以在插件里定義一個保存插件參數(shù)默認值的對象敞咧,同時將接收來的參數(shù)對象合并到默認對象上,最后就實現(xiàn)了用戶指定了值的參數(shù)使用指定的值偶翅,未指定的參數(shù)使用插件默認值默勾。

為了演示方便,再指定一個參數(shù)fontSize聚谁,允許調(diào)用插件的時候設(shè)置字體大小灾测。

$.fn.myPlugin = function(options) {
var defaults = {
    'color': 'red',
    'fontSize': '12px'
};
var settings = $.extend(defaults, options);
return this.css({
    'color': settings.color,
    'fontSize': settings.fontSize
});
}

現(xiàn)在,我們調(diào)用的時候指定顏色垦巴,字體大小未指定媳搪,會運用插件里的默認值12px。

$('a').myPlugin({
    'color': '#2C9929'
});

運行結(jié)果:

image.png

同時指定顏色與字體大兄栊:

$('a').myPlugin({
    'color': '#2C9929',
    'fontSize': '20px'
});

運行結(jié)果:

image.png

保護好默認參數(shù)

注意到上面代碼調(diào)用extend時會將defaults的值改變秦爆,這樣不好,因為它作為插件因有的一些東西應(yīng)該維持原樣憔披,另外就是如果你在后續(xù)代碼中還要使用這些默認值的話等限,當你再次訪問它時它已經(jīng)被用戶傳進來的參數(shù)更改了。

image.png

一個好的做法是將一個新的空對象做為$.extend的第一個參數(shù)芬膝,defaults和用戶傳遞的參數(shù)對象緊隨其后望门,這樣做的好處是所有值被合并到這個空對象上,保護了插件里面的默認值锰霜。

$.fn.myPlugin = function(options) {
var defaults = {
    'color': 'red',
    'fontSize': '12px'
};
var settings = $.extend({},defaults, options);//將一個空對象做為第一個參數(shù)
return this.css({
    'color': settings.color,
    'fontSize': settings.fontSize
});
}

到此筹误,插件可以接收和處理參數(shù)后,就可以編寫出更健壯而靈活的插件了癣缅。若要編寫一個復(fù)雜的插件厨剪,代碼量會很大哄酝,如何組織代碼就成了一個需要面臨的問題,沒有一個好的方式來組織這些代碼祷膳,整體感覺會雜亂無章陶衅,同時也不好維護,所以將插件的所有方法屬性包裝到一個對象上直晨,用面向?qū)ο蟮乃季S來進行開發(fā)搀军,無疑會使工作輕松很多。
喜歡本文的可以點關(guān)注喲~

請繼續(xù)關(guān)注勇皇,下一篇面向?qū)ο蟮膉Query插件開發(fā)罩句。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市儒士,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌檩坚,老刑警劉巖着撩,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異匾委,居然都是意外死亡拖叙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門赂乐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來薯鳍,“玉大人,你說我怎么就攤上這事挨措⊥诼耍” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵浅役,是天一觀的道長斩松。 經(jīng)常有香客問我,道長觉既,這世上最難降的妖魔是什么惧盹? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮瞪讼,結(jié)果婚禮上钧椰,老公的妹妹穿的比我還像新娘。我一直安慰自己符欠,他們只是感情好嫡霞,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著希柿,像睡著了一般秒际。 火紅的嫁衣襯著肌膚如雪悬赏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天娄徊,我揣著相機與錄音闽颇,去河邊找鬼。 笑死寄锐,一個胖子當著我的面吹牛兵多,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播橄仆,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼剩膘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了盆顾?” 一聲冷哼從身側(cè)響起怠褐,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎您宪,沒想到半個月后奈懒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡宪巨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年磷杏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捏卓。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡极祸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出怠晴,到底是詐尸還是另有隱情遥金,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布蒜田,位于F島的核電站汰规,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏物邑。R本人自食惡果不足惜溜哮,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望色解。 院中可真熱鬧茂嗓,春花似錦、人聲如沸科阎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蝌矛,卻和暖如春道批,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背入撒。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工隆豹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茅逮。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓璃赡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親献雅。 傳聞我的和親對象是個殘疾皇子碉考,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容