Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I tell if a node is in memory or in the dom?

Tags:

jquery

dom

I am working a lot with nodes before they are attached to the main page's DOM; and I need to perform some work depending on whether or not a given node is contained within the main document or not.

My current method is to walk up the parents, via:

if this.el$.closest("body").length > 0

Is there a more appropriate way to do this? (Preferrably one that doesn't have to walk all of the node's ancestors?)

like image 416
Jonathan Stanton Avatar asked Aug 13 '12 22:08

Jonathan Stanton


People also ask

How do I know if my element is still in DOM?

Use the getElementsByTagName to Check the Existence of an Element in DOM. The function getElementsByTagName() can return all elements with the specified tagName in DOM . The return of the function can be one or more elements or null if no element is found.

What are considered as nodes in DOM?

Nodes are in the DOM aka Document Object model. In the DOM, all parts of the document, such as elements, attributes, text, etc. are organized in a hierarchical tree-like structure; consisting of parents and children. These individual parts of the document are known as nodes.

What is the difference between node and element in DOM?

So, in a nutshell, a node is any DOM object. An element is one specific type of node as there are many other types of nodes (text nodes, comment nodes, document nodes, etc...). The DOM consists of a hierarchy of nodes where each node can have a parent, a list of child nodes and a nextSibling and previousSibling.

How do I select a node in DOM?

The most common methods for selecting/creating a list of nodes in an HTML document are: querySelectorAll() getElementsByTagName() getElementsByClassName()


1 Answers

You have several options which execute at several different speeds.

var $document = $(document);
var $element = $("#jq-footer");
var exists;

// Test if the element is within a body
exists = $element.closest("body").length;

// Test if the document contains an element
// wrong syntax, use below instead --> exists = $.contains($document, $element);
exists = $.contains(document.documentElement, $element[0]);

// Test if the element is within a body
$($element).parents().is("body");

// Manually loop trough the elements
exists = elementExists($element[0]);

// Used for manual loop
function elementExists(element) {
    while (element) {
        if (element == document) {
            return true;
        }
        element = element.parentNode;
    }
    return false;
}​

See Performance Test

For this test I copied a huge amount of html to traverse over, I copied the source of one of the jQuery pages into a fiddle, stripping out all the script tags leaving only the body and the html in between.

Feel free you use document instead of "body" and vice-versa or add more tests but it should give you the general idea.

Edit

I updated the performance test to use the correct syntax for contains as the previous one was incorrect and always returned true even if the element did not exist. the blow now returns true if the element exists but if you specify a selector which doesn't exist it will return false.

exists = $.contains(document.documentElement, $element[0]);

I also added the suggested alternative mentioned by MrOBrian in the comments of the question which is again slightly faster than contains.

Nice one MrOBrian.

Edit

Here is the jsPerf performance test with all the nice charts.

Thanks Felix Kling for spotting the issue and helping me fix the jsPerf tests.

Added more test results from the comments, this one is really good:
jsPerf performance test: dom-tree-test-exists

like image 185
Nope Avatar answered Oct 05 '22 01:10

Nope