自己動(dòng)手構(gòu)造API理解jQuery

封裝兩個(gè)函數(shù)钟沛,一個(gè)用來(lái)獲取某個(gè)節(jié)點(diǎn)的兄弟姐妹,一個(gè)用來(lái)給元素添加類
現(xiàn)在有一個(gè)無(wú)序列表。循序漸進(jìn)棉钧,體會(huì)jQuery設(shè)計(jì)思想。

<!-- ul>li[id=item$]{選項(xiàng)$}*5 -->
    <ul>
        <li id="item1">選項(xiàng)1</li>
        <li id="item2">選項(xiàng)2</li>
        <li id="item3">選項(xiàng)3</li>
        <li id="item4">選項(xiàng)4</li>
        <li id="item5">選項(xiàng)5</li>
    </ul>

封裝兩個(gè)函數(shù)

封裝一個(gè)獲取兄弟姐妹函數(shù)getSiblings

function getSiblings(node){  /* API */
    var allChildren = node.parentNode.children ;
    // 偽數(shù)組
    var array = {
        length: 0
    }
    // 獲取node的兄弟姐妹
    for (let i = 0; i < allChildren.length; i++){
        if(allChildren[i] !== node){
            // array是偽數(shù)組涕蚤,沒(méi)有push方法
            array[array.length] = allChildren[i];
            array.length += 1;
        }
    }
    return array
}

封裝添加類函數(shù)addClass

//添加的類用數(shù)組表示
function addClass(node,classes){
    classes.forEach(value => {
        node.classList.add(value)
    });
}

命名空間

兩個(gè)函數(shù)不能就這么隨意的放著宪卿,賦予一個(gè)命名空間

// getSiblings,addClass作為yyydom對(duì)象的方法
window.yyydom = {}
yyydom.getSiblings = getSiblings
yyydom.addClass = addClass

yyydom.addClass(item2,['a','b'])
//這種調(diào)用方式并不好的诵,我們希望將node節(jié)點(diǎn)放在前面

把node放在前面進(jìn)行調(diào)用

有兩種方法:

  1. 擴(kuò)展 Node 接口,直接在 Node.prototype 上加函數(shù)
  2. 自己創(chuàng)建新的接口

1.篡改Node.prototype佑钾,添加函數(shù)

Node.prototype.getSiblings = function(){
 var allChildren = this.parentNode.children ;
    // 偽數(shù)組
    var array = {
        length: 0
    }
    // 獲取node的兄弟姐妹
    for (let i = 0; i < allChildren.length; i++){
        if(allChildren[i] !== this){
            // array是偽數(shù)組西疤,沒(méi)有push方法
            array[array.length] = allChildren[i];
            array.length += 1;
        }
    }
    return array
}

Node.prototype.addClass2 = function(classes){
 classes.forEach(value => {
        this.classList.add(value)
    });
}
// 用call顯示this,call的第一個(gè)參數(shù)就是this
// item3.getSiblings()
// item3.getSiblings.call(item3) ,等價(jià)上
// item3.addClass(['q','w','e'])
// item3.addClass(item3,['q','w','e'])  等價(jià)上

但是休溶,在Node原型上增加方法也不好代赁,如果有多個(gè)人修改容易造成沖突。既然這樣兽掰,不如自己創(chuàng)建一個(gè)新Node構(gòu)造函數(shù)芭碍。自己動(dòng)手,豐衣足食孽尽。

2.自己創(chuàng)建新的接口(無(wú)侵入)

window.Node2 = function(node){
    return {
        getSiblings:function(){
            var allChildren = node.parentNode.children ;
            // 偽數(shù)組
            var array = {
            length: 0
            }
            // 獲取node的兄弟姐妹
            for (let i = 0; i < allChildren.length; i++){
            if(allChildren[i] !== node){
            // array是偽數(shù)組豁跑,沒(méi)有push方法
            array[array.length] = allChildren[i];
            array.length += 1;
            }
            }
            return array
        },
        addClass:function(classes){
            classes.forEach(value => {
                node.classList.add(value)
            });
        }
    }
}
var node2 = Node2(item3)
node2.getSiblings()
node2.addClass(['p','o'])

構(gòu)造函數(shù)Node2返回一個(gè)新對(duì)象,這個(gè)對(duì)象有g(shù)etSiblings和addClass兩個(gè)方法泻云,里面還是調(diào)用的原生API艇拍。似乎離目標(biāo)越來(lái)越近了。

Node2是隨意取的宠纯,改為jQuery卸夕,于是

var node2 = jQuery(item3)
node2.getSiblings()

再進(jìn)一步,window.$ = jQuery婆瓜,再省略window快集,于是就變成了

var node2 = $(item3)
node2.getSiblings()

是不是很熟悉呢?

選擇器多樣化

目前我們所創(chuàng)建的構(gòu)造函數(shù)只能獲取節(jié)點(diǎn)廉白,如果是其他選擇器呢个初,比如$('ul>li:nth-child(3)'),那么需要加一些判斷

window.jQuery = function(nodeOrSelector){
    //是否為字符串
    if(typeof nodeOrSelector === 'string'){
  //利用了原生的document.querySelector
        node = document.querySelector(nodeOrSelector)
    }else{
        node = nodeOrSelector
    }

    return {
        getSiblings:function(){
            var allChildren = node.parentNode.children ;
            // 偽數(shù)組
            var array = {
            length: 0
            }
            // 獲取node的兄弟姐妹
            for (let i = 0; i < allChildren.length; i++){
            if(allChildren[i] !== node){
            // array是偽數(shù)組,沒(méi)有push方法
            array[array.length] = allChildren[i];
            array.length += 1;
            }
            }
            return array
        },
        addClass:function(classes){
            classes.forEach(value => {
                node.classList.add(value)
            });
        }
    }

}

//獲取列表第五個(gè)元素
var node2 = jQuery('ul>li:nth-child(5)')
// 給我舊的對(duì)象猴蹂,返回新的對(duì)象
node2.addClass(['red'])

那么要獲取多個(gè)節(jié)點(diǎn)呢院溺,這是里面就要用到document.querySelectorAll,而且部分邏輯也有變化

window.jQuery2 = function(nodeOrSelector){
    let nodes  //最后要返回的對(duì)象
    if(typeof nodeOrSelector === 'string'){
        nodes = document.querySelectorAll(nodeOrSelector) //偽數(shù)組
    }else if(nodeOrSelector instanceof Node){
        // 保證返回結(jié)果一致磅轻,都為偽數(shù)組
        nodes = {
            0: nodeOrSelector,
            length: 1
        }
    }
   //添加類
    nodes.addClass = function(classes){
        classes.forEach((value) => {
            // 給nodes數(shù)組里每一項(xiàng)添加類
            for (let i = 0;i < nodes.length; i++){
                nodes[i].classList.add(value)
            }
        })
    }
    // 獲取元素文本
    nodes.getText = function(){
        var texts = []
        for(let i = 0;i < nodes.length;i++){
            texts.push(nodes[i].textContent)
        }
        return texts
    }
    // 設(shè)置文本
    nodes.setText = function(text){
        for(let i=0;i<nodes.length;i++){
            nodes[i].textContent = text
        }
    }
    // 兩者合并珍逸,這種在jQuery中非常常見(jiàn)
    nodes.text = function(text){
        if(text === undefined){
            var texts = []
            for(let i = 0;i < nodes.length;i++){
            texts.push(nodes[i].textContent)
            }
            return texts
        }else{
            for(let i=0;i<nodes.length;i++){
                nodes[i].textContent = text
            }
        }
    }
    return nodes
}
var node3 = jQuery2('ul>li')
node3.addClass(['red'])
node3.text('yyy')
//這大概就是最終體了
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市聋溜,隨后出現(xiàn)的幾起案子谆膳,更是在濱河造成了極大的恐慌,老刑警劉巖撮躁,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漱病,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)杨帽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門漓穿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人睦尽,你說(shuō)我怎么就攤上這事器净。” “怎么了当凡?”我有些...
    開(kāi)封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵山害,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我沿量,道長(zhǎng)浪慌,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任朴则,我火速辦了婚禮权纤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘乌妒。我一直安慰自己汹想,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布撤蚊。 她就那樣靜靜地躺著古掏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪侦啸。 梳的紋絲不亂的頭發(fā)上槽唾,一...
    開(kāi)封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音光涂,去河邊找鬼庞萍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛忘闻,可吹牛的內(nèi)容都是我干的钝计。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼服赎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼葵蒂!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起重虑,我...
    開(kāi)封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秦士,沒(méi)想到半個(gè)月后缺厉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年提针,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了命爬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辐脖,死狀恐怖饲宛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嗜价,我是刑警寧澤艇抠,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站久锥,受9級(jí)特大地震影響家淤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瑟由,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一絮重、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧歹苦,春花似錦青伤、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至痴施,卻和暖如春擎厢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辣吃。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工动遭, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人神得。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓厘惦,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親哩簿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宵蕉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

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

  • 概要 64學(xué)時(shí) 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,128評(píng)論 0 3
  • jQuery 是什么? jQuery實(shí)質(zhì)上是一個(gè)構(gòu)造函數(shù)节榜,接受一個(gè)參數(shù)羡玛,這個(gè)參數(shù)可能是節(jié)點(diǎn),然后返回一個(gè)方法對(duì)象去...
    夜未央_M閱讀 662評(píng)論 0 0
  • 最近開(kāi)始學(xué)習(xí) jQuery宗苍,jQuery 是 JavaScript最受歡迎的一個(gè)庫(kù)稼稿,它讓原本極不方便的JS DOM...
    不討喜的大雄閱讀 540評(píng)論 0 1
  • 首先要理解,JavaScript的語(yǔ)法是需要引擎來(lái)實(shí)現(xiàn)的.引擎是用其他語(yǔ)言寫的(一般是c或者java).因?yàn)镴av...
    joker731閱讀 199評(píng)論 0 1
  • 我給您沏的這一壺茉莉香片薄榛,也許是太苦了一點(diǎn)。我將要說(shuō)給您聽(tīng)的一段香港傳奇让歼,恐怕也是一樣的苦——香港是一個(gè)華美的但是...
    煜煙閱讀 441評(píng)論 0 0