如何将两个NodeList对象连接成一个,避免重复

时间:2017-12-21 13:57:47

标签: javascript

我正在编写一些函数来简化我与Javascript节点的交互,这是迄今为止的源代码:

Node.prototype.getClasses = function() {
    return this.className ? this.className.split(" ") : "";
};

Node.prototype.hasClass = function(c) {
    return this.getClasses().indexOf(c) >= 0;
};

Node.prototype.addClass = function(c) {
    if (!this.hasClass(c)) {
        this.className += " " + c;
    }
    return this;
};

Node.prototype.removeClass = function(c) {
    if (this.hasClass(c)) {
        var classes = this.getClasses();
        var newClasses = [];
        for (var index = 0; index < classes.length; index++) {
            if (classes[index] !== c) {
                newClasses.push(classes[index]);
            }
        }
        this.className = newClasses.join(" ");
    }
    return this;
};

function NodeCollection(nodes) {
    this.nodes = nodes;
    this.addClass = (c) => {
        for (var nodeIndex = 0; nodeIndex < this.nodes.length; nodeIndex++) {
            this.nodes[nodeIndex].addClass(c);
        }
        return this.nodes;
    };
    this.removeClass = (c) => {
        for (var nodeIndex = 0; nodeIndex < this.nodes.length; nodeIndex++) {
            this.nodes[nodeIndex].removeClass(c);
        }
        return this.nodes;
    };
    this.getHTML = () => {
        var output = "";
        for (var nodeIndex = 0; nodeIndex < this.nodes.length; nodeIndex++) {
            output += this.nodes[nodeIndex].outerHTML;
        }
        return output;
    };
    this.each = (f) => {
        for (var nodeIndex = 0; nodeIndex < this.nodes.length; nodeIndex++) {
            f(this.nodes[nodeIndex]);
        }
        return this.nodes;
    };
}

Node.prototype.query = function(s) {
    return new NodeCollection(this.querySelectorAll(s));
};

Node.prototype.siblings = function(s) {
    var rawSiblings = this.parentNode.querySelectorAll(s);
    var output = [];
    for (var siblingIndex = 0; siblingIndex < rawSiblings.length; siblingIndex++) {
        if ((rawSiblings[siblingIndex].parentNode === this.parentNode) && (rawSiblings[siblingIndex] !== this)) {
            output.push(rawSiblings[siblingIndex]);
        }
    }
    return new NodeCollection(output);
};

一切都很好,我对这些功能非常满意,我已经设法在没有使用Javascript框架(一个爱好项目)的情况下避免了很多麻烦。

现在,我希望能够为NodeCollection编写一个查询函数,但是,我不太清楚我应该如何连接nodes成员NodeCollection }对象,它们是NodeList的实例。我想写这样的东西作为NodeCollection的成员函数:

this.query = (s) => {
    //create an empty NodeList
    for (var index = 0; index < this.nodes.length; index++) {
        //concat this[nodes][index] to the node list created outside the 
        //cycle avoiding possible duplicates
    }
    //return the concatenated NodeList
};

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:3)

  

如何将两个NodeList对象连接成一个,避免重复

使用isSameNodeArray.from

Array.from( nodeList1 ).forEach( function( ele, index ){
  var isDuplicate = Array.from( nodeList2 ).some( ( ele2 ) => ele.isSameNode(ele2) );
  if ( !isDuplicate )
  {  
      nodeList2[ nodeList2.length ] = ele;
  }
})

现在nodeList2的所有节点都来自nodeList1,不是重复的。

<强>演示

&#13;
&#13;
var nodeList1 = Array.from( document.querySelectorAll(".a") );
var nodeList2 = Array.from( document.querySelectorAll(".b") );

console.log( "original length " + nodeList1.length, nodeList2.length );

nodeList1.forEach(function(ele, index) {
  var isDuplicate = nodeList2.some( ele2 => ele.isSameNode(ele2));
  //console.log( ele, isDuplicate );
  if (!isDuplicate) {
    nodeList2.push( ele );
  }
});

console.log( "Final length " + nodeList1.length , nodeList2.length );
&#13;
<div class="a b"></div>
<div class="a"></div>
<div class="b"></div>
<div class="a b"></div>
&#13;
&#13;
&#13;