jQuery方法原生js實現 --- siblings兄弟節點

今天工作失誤,導致移動端瀏覽器無法工作,初步估計是es6未經過編譯便進入項目。經驗欠缺,吃一塹長一智吧。

工作中用到兄弟節點的地方不算太多,或許選項卡,輪播圖會用到。爲了對jQuery進一步深入,特意研究一下siblings()方法。

<ul>
    <div id="sibling1">1</div>
    <div class="sibling">2</div><div></div>  
    <div class="sibling">3</div>
    <div class="sibling"><p>4</p></div>
    <div class="sibling">5</div>   
    <p>11</p>
    </ul>

siblings = (o)=>{
    let arr = [] ; //保存兄弟節點
    let prev = o.previousSibling; //o的前一個同胞節點
    //先往上查詢兄弟節點
    while(prev){
        if(prev.nodeType == 1){
            arr.unshift(prev);//數組首部插入數組,保證節點順序
        }
        prev = prev.previousSibling;//把上一節點賦值給prev
    }
    //往下查詢兄弟節點
    let next = o.nextSibling;//o的後一個同胞節點
    while(next){
        if(next.nodeType == 1){
            arr.push(next);//數組尾部插入,保證節點順序
        }
        next = next.nextSibling;//下一節點賦值給next,用於循環
    }
    return arr;
}

let odiv = document.getElementById('sibling1');

console.log(siblings(odiv));

上面代碼主要用到previousSibling和nextSibling兩個html屬性,分別用來獲取同胞節點。但是以上代碼存在嚴重缺點,他的同胞元素經過實驗指的是同一級別的元素,就好比上面div兄弟元素,會把同級別p標籤,值爲11那個p標籤包含進去,如果沒有ul包着,script也會包含進去,因爲同一級別。

這不是我們想要的,所以要過濾部分不符合元素。過濾依據就是當前標籤名,例如要找div標籤兄弟,那麼就要對同胞元素標籤進行比較,代碼如下


//js實現jQuery的siblings()函數

siblings = (o)=>{
    let arr = [] ; //保存兄弟節點
    let prev = o.previousSibling; //o的前一個同胞節點
    //先往上查詢兄弟節點
    while(prev){
        if(prev.nodeType == 1&&prev.tagName == o.tagName){
            arr.unshift(prev);//數組首部插入數組,保證節點順序
        }
        prev = prev.previousSibling;//把上一節點賦值給prev
    }
    //往下查詢兄弟節點
    let next = o.nextSibling;//o的後一個同胞節點
    while(next){
        if(next.nodeType == 1 &&next.tagName == o.tagName){
            arr.push(next);//數組尾部插入,保證節點順序
        }
        next = next.nextSibling;//下一節點賦值給next,用於循環
    }
    return arr;
}

let odiv = document.getElementById('sibling1');

console.log(siblings(odiv));

通過tagName屬性取得標籤名,而後對比判斷過濾即可。老規矩,仿照jQuery鏈式調用。


class aQuery {
    constructor(seletor){
        this.arr = [] ; //保存兄弟節點
        this.seletor = document.querySelector(seletor);
    }
    siblings(){      
        let prev = this.seletor.previousSibling; //o的前一個同胞節點
        //先往上查詢兄弟節點
        while(prev){
            if(prev.nodeType == 1&&prev.tagName == this.seletor.tagName){
                this.arr.unshift(prev);//數組首部插入數組,保證節點順序
            }
            prev = prev.previousSibling;//把上一節點賦值給prev
        }
        //往下查詢兄弟節點
        let next = this.seletor.nextSibling;//o的後一個同胞節點
        while(next){
            if(next.nodeType == 1 &&next.tagName == this.seletor.tagName){
                this.arr.push(next);//數組尾部插入,保證節點順序
            }
            next = next.nextSibling;//下一節點賦值給next,用於循環
        }
        
        return this;
    }
}
console.log(new aQuery('#sibling1').siblings().arr)

爲了省事,直接用es6的類class構造,不過並沒有實現無new構造,下次有空再補上



參考鏈接 :

http://www.zhufengpeixun.cn/jishuziliao/javaScriptzhuanti/2011-07-21/130.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章