I am writing a few functions to simplify my interaction with Javascript Nodes, here is the source-code so far:
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 is working great and I am quite content with these functions, I have managed to prevent a lot of headaches without the usage of Javascript frameworks (a hobby project).
Now, I would like to be able to write a query function for NodeCollection
as well, however, I am not quite aware of how should I concatenate the nodes
members of the NodeCollection
objects, which 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?
How to concatenate 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;
}
})
Now nodeList2
has all the nodes from nodeList1
which are not duplicates.
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="a b"></div>
<div class="a"></div>
<div class="b"></div>
<div class="a b"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With