How to merge two NodeList objects into one, avoiding duplicates

I am writing several functions to simplify my interaction with Javascript Nodes, here is the source code:

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); }; 

Everything works fine, and I'm quite happy with these features, I managed to prevent a lot of headaches without using the Javascript framework (a hobby project).

Now I would also like to write a query function for NodeCollection , however I do not quite understand how I should concatenate the members of the nodes of NodeCollection objects that are instances of NodeList . I would like to write something like this as a member function of 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 }; 

How can i achieve this?

+7
javascript
source share
1 answer

How to merge two NodeList objects into one, avoiding duplicates

Use isSameNode and Array.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 now has all the nodes from nodeList1 that are not duplicated.

Demo

 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 ); 
 <div class="ab"></div> <div class="a"></div> <div class="b"></div> <div class="ab"></div> 
+3
source share

All Articles