jQuery方法原生js实现 --- siblings兄弟节点

今天工作失误,导致移动端浏览器无法工作,初步估计是es6未经过编译便进入项目。经验欠缺,吃一堑长一智吧。

工作中用到兄弟节点的地方不算太多,或许选项卡,轮播图会用到。为了对jQuery进一步深入,特意研究一下siblings()方法。

    1
    2
    3

    4

    5

    11


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


你可能感兴趣的:(jQuery源码学习,网页前端)