32
loading...
This website collects cookies to deliver better user experience
The Node.contains() method returns a Boolean value indicating whether a node is a descendant of a given node, i.e. the node itself, one of its direct children (childNodes), one of the children's direct children, and so on.
Node.prototype.contains(...)
already exists. I want another name for our custom function. Let's google synonym of contains
coz Array
and String
have includes as well in their prototypes. prototype
and expecting to use it like so :-document.includes(document.body)
, document
can be accessed inside the includes
function via this
keyword. Node.prototype.includes
in 4 different ways :-1 Node.prototype.includes = function(node){
2 const currentNode = this;
3 if(!currentNode)
4 return false;
5 if(currentNode===node)
6 return true;
7 let isNodeFound = false;
8 for(let index = 0;index<currentNode.childNodes.length;index++){
9 isNodeFound = isNodeFound || currentNode.childNodes[index].includes(node);
10 if(isNodeFound) return true;
11 }
12 return false;
13 }
currentNode
to this
and If currentNode
doesn't exist, simply return false
.currentNode
is equal to node
return true
.isNodeFound
to false
. Then loop over childNodes
of the currentNode
and on each child, call the includes
method again to check if they include the node
element. If they do, isNodeFound
will ultimately become true
since it is being Orrrrrrd with the results coming from respective childNodes
and reassigned to itself. Once isNodeFound
is true
, we don't need to loop over rest of the childNodes
of currentNode
and exit early by returning true
else ultimately return false
.1 Node.prototype.includes = function (node) {
2 const queue = [];
3 let currentNode = this;
4 queue.push(currentNode);
5 while (queue.length) {
6 currentNode = queue.shift();
7 if (currentNode === node) return true;
8 if (currentNode.hasChildNodes()) {
9 queue.push(...currentNode.childNodes);
10 }
11 }
12 return false;
13 };
queue
. Set currentNode
to this
and push
(or enqueue to be specific) it. queue
is not empty, dequeue the currentNode
from front of the queue
(using shift
here). If currentNode
is equal to node
then return true
. Otherwise enqueue the childNodes
of currentNode
(using push
here). Once we are out of the while
loop, we have traversed all the nodes and can safely say that we couldn't find the node
and return false
.pop
instead of shift
and obviously for the sake of consistency, rename queue
to stack
.1 Node.prototype.includes = function (node) {
2 const currentNode = this;
3 if (!currentNode)
4 return false;
5 if (currentNode === node) return true;
6 return !!(currentNode.firstChild?.includes(node) || currentNode.nextSibling?.includes(node))
7 };
currentNode
to this
and if currentNode
doesn't exist, return false
.currentNode
is equal to node
return true
firstChild
includes the node
OR current node's nextSibling
includes the node
. Also notice the !!
. That's because I have used the ?
operator due to which we can end up with undefined || undefined
condition or false || undefined
condition where both evaluate to undefined
which is a falsy value and so !!
will ensure undefined
coerces to false
. 1 Node.prototype.includes = function(node){
2 const currentNode = this;
3 while(node){
4 if(currentNode===node) return true;
5 node = node.parentNode;
6 }
7 return false;
8 }
node
exists, we check if currentNode
is equal to node
and if it is we return true
, else the node
is made to point to it's parentNode
for further comparisons. If we exit the while
loop, it's safe to say that the node
isn't a contained within the currentNode
and thus, return false
.