《鋒利的jQuery》十溪掀、jQuery插件的寫法


title: 《鋒利的jQuery》十歇式、jQuery插件的使用和寫法
date: 2017-07-24 06:20:00
tags: 鋒利的jQuery


編寫插件的目的是給已有的一系列方法或函數(shù)做一個(gè)封裝屁置,以便在其他地方重復(fù)使用疆虚,方便后期維護(hù)和提高開發(fā)效率搞监。

插件的種類

1.封裝對(duì)象方法的插件

這種插件是將對(duì)象方法封裝起來(lái)水孩,用于通過(guò)選擇器獲取jQuery對(duì)象進(jìn)行操作,是最常見(jiàn)的一種插件琐驴。比如parent()俘种、appendTo()秤标、addClass()等。

2.封裝全局函數(shù)的插件

可以將獨(dú)立的函數(shù)加載到j(luò)Query的命名空間之下宙刘。例如$.ajax()苍姜、$.trim()等。

3.選擇器插件

個(gè)別情況下悬包,會(huì)需要使用到選擇器插件衙猪,雖然jQuery的選擇器十分強(qiáng)大,但還是會(huì)需要擴(kuò)充一些自己喜歡的選擇器布近。

插件的基本要點(diǎn)

插件的文件名推薦命名為jquery.[插件名].js垫释。

所有的對(duì)象方法都應(yīng)該附加到j(luò)Query.fn對(duì)象上,而所有的全局函數(shù)都應(yīng)該附加到j(luò)Query對(duì)象本身上撑瞧。

在插件內(nèi)部饶号,this只想的是當(dāng)前通過(guò)選擇器獲取的jQuery對(duì)象,例如click()方法指向的是DOM元素季蚂∶4可以通過(guò)this.each來(lái)遍歷所有元素。

插件應(yīng)該返回一個(gè)jQuery對(duì)象扭屁,以保證插件的可鏈?zhǔn)讲僮魉闾浮3遣寮枰祷氐氖且恍┬枰@取的量,例如字符串或者數(shù)組料滥。

避免在插件內(nèi)部使用$作為jQuery對(duì)象的別名然眼,而應(yīng)該用完整的jQuery來(lái)表示。這樣可以避免沖突葵腹,如果使用$作為jQuery的別名高每,要用必報(bào)來(lái)避免沖突。

插件中的閉包

利用閉包的特性践宴,既可以避免內(nèi)部臨時(shí)變量影響全局空間鲸匿,又可以在插件內(nèi)部繼續(xù)使用$作為jQuery別名。

(function($){        // 將$作為匿名函數(shù)的形參
    // 這里編寫插件的代碼
    var foo;
    var bar = function(){
          // 在匿名函數(shù)內(nèi)部的函數(shù)都可以訪問(wèn)foo阻肩,即便是在匿名函數(shù)的外部調(diào)用bar()的時(shí)候带欢,也可以在bar()的內(nèi)部訪問(wèn)到foo,但在匿名函數(shù)的外部直接訪問(wèn)foo是做不到的烤惊。
    }

    // 下面的語(yǔ)句讓匿名函數(shù)內(nèi)部的函數(shù)bar()返回到全局可訪問(wèn)的范圍內(nèi)乔煞,這樣就可以在匿名函數(shù)的外部通過(guò)調(diào)用jQuery.BAR()來(lái)訪問(wèn)內(nèi)部定義的函數(shù)bar(),并且內(nèi)部函數(shù)bar()也能訪問(wèn)匿名函數(shù)內(nèi)的變量foo柒室。
    $.BAR = bar;
})(jQuery)        // jQuery作為實(shí)參傳遞給匿名函數(shù)

jQuery的插件機(jī)制

jQuery提供了兩個(gè)用于擴(kuò)展jQuery功能的方法渡贾,jQuery.fn.extend()方法和jQuery.extend()方法。第一個(gè)方法用于封裝對(duì)象方法的插件雄右,第二個(gè)適用于封裝全局函數(shù)插件和選擇器插件空骚。這兩個(gè)方法都接收一個(gè)參數(shù)纺讲,類型是Object。

jQuery.extend()除了擴(kuò)展插件能用到府怯,還有一個(gè)用處是擴(kuò)展已有的對(duì)象刻诊,也就是傳遞兩個(gè)參數(shù),類型都是object牺丙,第二個(gè)對(duì)象會(huì)和第一個(gè)對(duì)象合并则涯,相同的屬性第二個(gè)會(huì)覆蓋第一個(gè)。

var settings = { validate: false , limit: 5 , name: 'foo' };
var options = { validate: true , name: 'bar' };
var newObj = jQuery.extend(settings,options);
console.log(newObj)      // { validate: true , limit: 5 , name: 'bar' }

所以jQuery.extend()方法經(jīng)常用于設(shè)置插件方法的一些默認(rèn)參數(shù)冲簿。

編寫jQuery插件

封裝jQuery對(duì)象插件

設(shè)置和獲取顏色的插件

首先編寫設(shè)置和獲取顏色的插件color粟判。該插件的功能是:

  1. 設(shè)置匹配元素的顏色
  2. 獲取匹配的元素(元素集合中的第一個(gè))的顏色。

由于是在jQuery對(duì)象上擴(kuò)展方法所以使用jQuery.fn.extend峦剔,這里要注意的是插件擴(kuò)展內(nèi)部的this指的是jQuery對(duì)象而不是普通的dom對(duì)象档礁,然后插件如果不是返回字符串之類的特定值,應(yīng)當(dāng)使其具有可鏈接性吝沫,為此要直接返回這個(gè)this對(duì)象呻澜。

(function($){
    $.fn.extend({
        'color': function(value){
            if(value == undefined){      
                return this.css('color');      // 獲取顏色。css方法本身就默認(rèn)返回第一個(gè)的顏色
            }else{        
                return this.each(function(){
                    $(this).css('color',value);     // 設(shè)置顏色惨险,由于this是jQuery對(duì)象羹幸,所以不需要each遍歷
                })
            }
        }
    });
})(jQuery)

表格隔行變色插件

(function($){
    $.fn.extend({
        'alterBgColor': function(options){
            options = $.extend({
                odd: 'odd',        // 偶數(shù)行樣式
                even: 'even',      // 奇書行樣式
                selected: 'selected'       // 選中行樣式
            },options);
            $('tbody>tr:odd' , this).addClass(options.odd);
            $('tbody>tr:even' , this).addClass(options.even);
            $('tbody>tr' , this).click(function(){
                // 判斷當(dāng)前是否選中
                var hasSelected = $(this).hasClass(options.selected);
                // 如果選中,則移出selected類辫愉,否則就加上selected類
                $(this)[hasSelected ? 'removeClass' : 'addClass'](options.selected).find(':checkbox').prop('checked',!hasSelected);
             });
             // 如果單選框默認(rèn)情況下是選擇的栅受,則高亮
             $('tbody>tr:has(:checked)' , this).addClass(options.selected);
             return this;       // 返回this,可以繼續(xù)鏈?zhǔn)讲僮?        }
    });
})(jQuery)

需要注意的是上面兩個(gè)插件內(nèi)部this都是可以匹配多個(gè)元素恭朗,但是如果遇到只能匹配一個(gè)元素的時(shí)候屏镊,要each遍歷匹配的jQuery對(duì)象,而在each內(nèi)部痰腮,this就是dom對(duì)象不是jQuery對(duì)象了而芥。

封裝全局函數(shù)

這類插件是在jQuery命名空間內(nèi)部添加一個(gè)函數(shù)。

增加兩個(gè)函數(shù)诽嘉,用于去除左側(cè)空格和右側(cè)空格蔚出。

(function($){
    $.extend({
        ltrim: function(text){
            // 假如text是undefined等非正確參數(shù),就取空字符串虫腋,防止replace方法報(bào)錯(cuò)
            return (text || '').replace(/^\s+/g,'');
        },
        rtrim: function(text){
            return (text || '').replace(/\s+$/g,'');
        }
    })
})(jQuery)

由于是全局函數(shù),所以要由jQuery或者$調(diào)用稀余,不能用jQuery對(duì)象去調(diào)用悦冀。

$.ltrim('         text');
$.rtrim('text        ');

自定義選擇器

jQuery提供了一套方法讓用戶客戶以通過(guò)制作選擇器插件來(lái)使用自定義選擇器。jQuery選擇器執(zhí)行的步驟如下:

  1. jQuery的選擇符解析器首先會(huì)使用一組正則表達(dá)式來(lái)解析選擇器

  2. 針對(duì)解析出的每個(gè)選擇符執(zhí)行一個(gè)選擇器函數(shù)

  3. 根據(jù)這個(gè)函數(shù)返回的是true還是false來(lái)決定是否保留這個(gè)元素睛琳。

按照上面的步驟盒蟆,以$('div:gt(1)')來(lái)舉例:

  1. 選擇器首先獲取所有的div元素

  2. 逐個(gè)將這些div元素作為參數(shù)踏烙,連同括號(hào)里的1等一些參數(shù)一起傳遞給gt對(duì)應(yīng)的選擇器函數(shù)進(jìn)行判斷

  3. 如果gt對(duì)應(yīng)的選擇器函數(shù)返回true則這個(gè)div元素保留,如果返回false則不保留历等,這樣得到的結(jié)果就是一個(gè)符合要求的div元素集合

現(xiàn)在來(lái)看一下最關(guān)鍵的gt的選擇器函數(shù):

gt: function(a,i,m){
     return i > m[3] - 0;
}

選擇器一共接受三個(gè)參數(shù):

第一個(gè)參數(shù)為a讨惩,指向的是當(dāng)前遍歷到的dom元素。

第二個(gè)參數(shù)為i寒屯,指的是當(dāng)前遍歷到的dom元素的索引值荐捻,從0開始。

第三個(gè)參數(shù)m最為特別寡夹,它是由jQuery正則解析引擎進(jìn)一步解析后的產(chǎn)物(用match匹配出來(lái)的)处面,m是一個(gè)數(shù)組。在這時(shí)m[3]的值就是'1'菩掏。
m[0]的值是:gt(1)
m[1]的值是:
m[2]的值是gt
m[4]在上面的例子沒(méi)有體現(xiàn)魂角,假如是div:l(ss(dd))這樣一個(gè)選擇器,m[4]就指向了(dd)這部分智绸,另外這里的m[3]的值就是ss(dd)野揪。

編寫一個(gè)between選擇器

例如使用$('div:between(2,5)')能實(shí)現(xiàn)獲取索引3、4元素的功能瞧栗。

選擇器僅僅是jQuery.expr[':']對(duì)象的一部分斯稳,所以這里是將between函數(shù)擴(kuò)展到jQuery.expr[':']對(duì)象中。

(function($){
    $.extend(jQuery.expr[':'],{
        between: function(a,i,m){
            var tmp = m[3].split(',');    // 將m[3]'最小值,最大值'改為['最小值','最大值']
            return tmp[0] - 0 < i && i < tmp[1] - 0;      // 將索引與最小和最大值進(jìn)行比較沼溜,符合要求的返回true平挑,這里-0 是隱式轉(zhuǎn)換的意思
        }
    })
})(jQuery)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市系草,隨后出現(xiàn)的幾起案子通熄,更是在濱河造成了極大的恐慌,老刑警劉巖找都,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唇辨,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡能耻,警方通過(guò)查閱死者的電腦和手機(jī)赏枚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)晓猛,“玉大人饿幅,你說(shuō)我怎么就攤上這事〗渲埃” “怎么了栗恩?”我有些...
    開封第一講書人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)洪燥。 經(jīng)常有香客問(wèn)我磕秤,道長(zhǎng)乳乌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任市咆,我火速辦了婚禮汉操,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蒙兰。我一直安慰自己磷瘤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開白布癞己。 她就那樣靜靜地躺著膀斋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪痹雅。 梳的紋絲不亂的頭發(fā)上仰担,一...
    開封第一講書人閱讀 52,785評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音绩社,去河邊找鬼摔蓝。 笑死,一個(gè)胖子當(dāng)著我的面吹牛愉耙,可吹牛的內(nèi)容都是我干的贮尉。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼朴沿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼猜谚!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起赌渣,我...
    開封第一講書人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤魏铅,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后坚芜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體览芳,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年鸿竖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沧竟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缚忧,死狀恐怖悟泵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闪水,我是刑警寧澤魁袜,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站敦第,受9級(jí)特大地震影響峰弹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芜果,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一鞠呈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧右钾,春花似錦蚁吝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至脆烟,卻和暖如春山林,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背邢羔。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工驼抹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拜鹤。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓框冀,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親敏簿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子明也,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361

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

  • 原文鏈接 http://blog.poetries.top/2016/10/20/review-jQuery 關(guān)注...
    程序員poetry閱讀 16,650評(píng)論 18 503
  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式。設(shè)計(jì)者無(wú)需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性惯裕。 1....
    LaBaby_閱讀 1,350評(píng)論 0 2
  • (續(xù)jQuery基礎(chǔ)(1)) 第5章 DOM節(jié)點(diǎn)的復(fù)制與替換 (1)DOM拷貝clone() 克隆節(jié)點(diǎn)是DOM的常...
    凜0_0閱讀 1,348評(píng)論 0 8
  • 二期學(xué)員行雨第11天作業(yè)温数。 1.你是如何看待覺(jué)悟的?你滿意自己的現(xiàn)狀嗎轻猖? 咋一看帆吻,標(biāo)題就很讓人醍醐灌頂×撸“很多人一...
    百齡語(yǔ)閱讀 242評(píng)論 0 0
  • 中秋節(jié)有悠久的歷史猜煮,和其它傳統(tǒng)節(jié)日一樣,也是慢慢發(fā)展形成的败许,古代帝王有春天祭日王带,秋天祭月的禮制,早在《周禮》一書中...
    上官書函閱讀 347評(píng)論 0 5