How can I check if an element exists in the visible DOM?

1,180,338

Solution 1

It seems some people are landing here, and simply want to know if an element exists (a little bit different to the original question).

That's as simple as using any of the browser's selecting method, and checking it for a truthy value (generally).

For example, if my element had an id of "find-me", I could simply use...

var elementExists = document.getElementById("find-me");

This is specified to either return a reference to the element or null. If you must have a Boolean value, simply toss a !! before the method call.

In addition, you can use some of the many other methods that exist for finding elements, such as (all living off document):

  • querySelector()/querySelectorAll()
  • getElementsByClassName()
  • getElementsByName()

Some of these methods return a NodeList, so be sure to check its length property, because a NodeList is an object, and therefore truthy.


For actually determining if an element exists as part of the visible DOM (like the question originally asked), Csuwldcat provides a better solution than rolling your own (as this answer used to contain). That is, to use the contains() method on DOM elements.

You could use it like so...

document.body.contains(someReferenceToADomElement);

Solution 2

Use getElementById() if it's available.

Also, here's an easy way to do it with jQuery:

if ($('#elementId').length > 0) {
  // Exists.
}

And if you can't use third-party libraries, just stick to base JavaScript:

var element =  document.getElementById('elementId');
if (typeof(element) != 'undefined' && element != null)
{
  // Exists.
}

Solution 3

Using the Node.contains DOM API, you can check for the presence of any element in the page (currently in the DOM) quite easily:

document.body.contains(YOUR_ELEMENT_HERE);

CROSS-BROWSER NOTE: the document object in Internet Explorer does not have a contains() method - to ensure cross-browser compatibility, use document.body.contains() instead.

Solution 4

I simply do:

if(document.getElementById("myElementId")){
    alert("Element exists");
} else {
    alert("Element does not exist");
}

It works for me and had no issues with it yet...

Solution 5

I prefer to use the node.isConnected property (Visit MDN).

Note: This will return true if the element is appended to a ShadowRoot as well, which might not be everyone's desired behaviour.

Example:

const element = document.createElement('div');
console.log(element.isConnected); // Returns false
document.body.append(element);
console.log(element.isConnected); // Returns true
Share:
1,180,338
Justin Bull
Author by

Justin Bull

A senior full-stack web developer with 10+ years of experience working with industry leaders to create innovative products for some of BC’s largest companies.

Updated on July 08, 2022

Comments

  • Justin Bull
    Justin Bull almost 2 years

    How do you test an element for existence without the use of the getElementById method?

    I have set up a live demo for reference. I will also print the code on here as well:

    <!DOCTYPE html>
    <html>
    <head>
        <script>
        var getRandomID = function (size) {
                var str = "",
                    i = 0,
                    chars = "0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ";
                while (i < size) {
                    str += chars.substr(Math.floor(Math.random() * 62), 1);
                    i++;
                }
                return str;
            },
            isNull = function (element) {
                var randomID = getRandomID(12),
                    savedID = (element.id)? element.id : null;
                element.id = randomID;
                var foundElm = document.getElementById(randomID);
                element.removeAttribute('id');
                if (savedID !== null) {
                    element.id = savedID;
                }
                return (foundElm) ? false : true;
            };
        window.onload = function () {
            var image = document.getElementById("demo");
            console.log('undefined', (typeof image === 'undefined') ? true : false); // false
            console.log('null', (image === null) ? true : false); // false
            console.log('find-by-id', isNull(image)); // false
            image.parentNode.removeChild(image);
            console.log('undefined', (typeof image === 'undefined') ? true : false); // false ~ should be true?
            console.log('null', (image === null) ? true : false); // false ~ should be true?
            console.log('find-by-id', isNull(image)); // true ~ correct but there must be a better way than this?
        };
        </script>
    </head>
    <body>
        <div id="demo"></div>
    </body>
    </html>
    

    Basically the above code demonstrates an element being stored into a variable and then removed from the DOM. Even though the element has been removed from the DOM, the variable retains the element as it was when first declared. In other words, it is not a live reference to the element itself, but rather a replica. As a result, checking the variable's value (the element) for existence will provide an unexpected result.

    The isNull function is my attempt to check for an elements existence from a variable, and it works, but I would like to know if there is an easier way to accomplish the same result.

    PS: I'm also interested in why JavaScript variables behave like this if anyone knows of some good articles related to the subject.

    • None
      None about 13 years
      Actually it is a live reference to the element itself, it's just not in a document any more. That functionality is required because you can actually pull an element out of the DOM and then put it back in later with all event handlers/etc still attached to it. As for why JS variables act like that? Because it would be incredibly annoying if they didn't. JS only deletes variables when you no longer have ANY references to them. The language has no way of knowing which references you deem important and which you think are worthless.
    • Justin Bull
      Justin Bull about 13 years
      @cwolves Interesting. I've encountered this many times before and never really thought much of it. In fact, in my current project, I'm saving elements in an array before I make any changes to them, just in case I want to revert the changes.
    • RobG
      RobG about 13 years
      Garbage collection runs from time to time and deletes everything it thinks it can. It seems pretty lousy in most browsers, but is getting better as developers realise that some browsers run for days or weeks between restarts, so good garbage collection is vital for browser performance. Web developers can help by deleting properties (and hence references to things in memory) that are no longer required.
    • Anthony DiSanti
      Anthony DiSanti over 12 years
      @JustinBull be careful with storing copies of the elements to revert. When storing a DOM element in an array, a reference to the DOM element is stored, not a copy, so changes made to the DOM element will be reflected when referencing the array's element. This is the case with all objects in javascript (variables of type 'object').
  • Justin Bull
    Justin Bull about 13 years
    Exactly what i was looking for! So obviously lol, why didn't I think of that. Also, do you know of any good articles that explain why variables act like this?
  • user3167101
    user3167101 about 13 years
    @Jabes88 I don't know of any of the top of my head sorry. As for why, I can only speculate.
  • Justin Bull
    Justin Bull about 13 years
    For the project I'm working on, I'm not able to use a library. Good-ol' fashion raw code only. I'm aware of that jQuery method, but it does not work on elements not wrapped in the jQuery container. For example, $('#elementId')[0].length would not produce the same result.
  • Justin Bull
    Justin Bull about 13 years
    I noticed just checking parentNode is good enough (will be null if element is removed). Would you say this is just as good? jsBin
  • user3167101
    user3167101 about 13 years
    @Jabes88 Good thinking. If it works on all browsers, then go for it :)
  • Justin Bull
    Justin Bull about 13 years
    Ack! Simply checking parentNode does not work in IE7 or IE8. However, your suggested method seems to work in all versions of IE as well as Chrome, FF, Safari, and Opera. Thanks again for your help.
  • andras
    andras over 12 years
    @JustinBull, well simply checking for parentNode won't work anywhere. If your element's parent has been removed from the DOM, then your element will have a parentNode, but won't be part of the DOM
  • bennedich
    bennedich about 12 years
    Even shorter: var elementInDom = function( el ) { while ( el = el.parentNode ) if ( el === document ) return true; return false; }
  • Mike
    Mike about 12 years
    To say this is wrong, I also had to prove to myself this was incorrect. So to explain, type this in your browser's console: $('body').parent(); vs $('<div id="#elementId"></div>').parent();. Both return 1 for .length - but you'll see that the body has a parent, and if you do enough .parent().parent() you'll reach the document which is the top of the DOM Tree. While on the other hand, <div> exists in memory and has no parent, but returns length of 1 which just counts the elements in the jQuery object. I suggest editing your question to keep SO clean :)
  • kayahr
    kayahr over 11 years
    Is there any good reason for such a complicated if statement in the second code example? Why not simply if (element) {}? When element is undefined or null then this expression is false. If element is a DOM element then the expression is true.
  • user3167101
    user3167101 about 11 years
    @kayahr It is far too complicated. getElementById() is spec'd to return null if it didn't find the element, so checking for a truthy returned value is all that's needed.
  • Buttle Butkus
    Buttle Butkus about 11 years
    Your answer did not work for me. I used getElementById and then checked for null and undefined as in Kon's answer. if(myElement != null && typeof myElement !== 'undefined') { etc...
  • user3167101
    user3167101 about 11 years
    @ButtleButkus Read the actual question. That solution you used doesn't make sense as getElementById() will return a reference to a DOM element or null, therefore, using typeof (especially on the RHS) is wrong (if it weren't defined, the LHS condition would throw a ReferenceError).
  • Buttle Butkus
    Buttle Butkus about 11 years
    I see now the asker did not want to use getElementById for some reason. Still, the code did not work for me, perhaps due to some other issue. But it seems like it worked for others. Unfortunately I can't take back my downvote unless you edit the question. If you make some minor edit I will gladly undo the vote.
  • user3167101
    user3167101 about 11 years
    This has nothing to do with the original question though. The OP wants to know if a reference to a DOM element is part of the visible DOM or not.
  • burak emre
    burak emre about 11 years
    Note that the element must have an id to be able catch via getElementById()
  • Kon
    Kon about 11 years
    I think that's just common sense.
  • poby
    poby about 11 years
    I know this is an old question but this answer is exactly the kind of elegant simple solution to the question which I was looking for.
  • Grinn
    Grinn almost 11 years
    ...or $(document).find(yourElement).length !== 0
  • kayahr
    kayahr almost 11 years
    @poby: It might seem elegant but it isn't really doing what was requested. It only checks if the element has a parent element. This doesn't imply that the element is in the visible DOM because maybe the parent element is not connected to it.
  • crush
    crush almost 11 years
    This seems like the ultimate answer to this problem...and its support, if MDN is to be believed is quite good.
  • crush
    crush almost 11 years
    Is there any reason to use this over what was posted below: document.body.contains() which seems to have very good browser support?
  • user3167101
    user3167101 almost 11 years
    @crush Just saw it. Doesn't look like it. I'll put a pointer in my answer to that one.
  • user3167101
    user3167101 almost 11 years
    This is the best answer. Note that just checking document.contains() should be enough.
  • user3167101
    user3167101 almost 11 years
    @csuwldcat It worked for me, at least in Chrome with document.contains(document.documentElement). document does have Node on its prototype chain, as far as I can tell (document->HTMLDocument->Document->Node)
  • user3167101
    user3167101 almost 11 years
    @csuwldcat I was trying to make it visible because this answer is the accepted one. The edit was meant to convey hey, csuwldcat has this better answer but you probably won't find it below, now you can follow this link and you should vote for it. It wasn't done to be un-nice in any way. If you still feel that way, feel free to edit my answer. It will go into the moderation queue for the community to decide.
  • csuwldcat
    csuwldcat almost 11 years
    @alex - no, you're right - your answer has a ton of votes and is the selected one, so it's probably better that the solution appears for people first.
  • user3167101
    user3167101 over 10 years
    @JohnSyrinek That was the question.
  • user3167101
    user3167101 over 10 years
    This exploits that null == undefined. The real returned value would be undefined. Comparing it against null is a bit weird.
  • Arek Bal
    Arek Bal about 10 years
    One would have to go through all parent of parents to find out if last one is document. The other problem is it still could be outside of visible range or be covered or be not visible because of many other reasons.
  • bozdoz
    bozdoz almost 10 years
    if the element has an id, if (document.getElementById('elementId')) ... is the obvious answer. +1
  • Admin
    Admin over 9 years
    An element could also have a parentNode only by virtue of having been appended to a document fragment.
  • Admin
    Admin over 9 years
    getElementById should never return undefined. In any case, the element != null check would pick this up.
  • Nikos M.
    Nikos M. over 9 years
    +1, does this work for (arbitrary) text nodes (or comment nodes) as well?
  • Ekramul Hoque
    Ekramul Hoque over 9 years
    @NikosM. It should work in any html tag but I didn't test it.
  • DoctorDestructo
    DoctorDestructo over 9 years
    I didn't even know there was baseURI property on DOM nodes. What I like about this approach is that it uses a property of the element itself, which presumably means it would work even if the element is in a different document (e.g. an iframe). What I don't like about it is that it doesn't seem to work outside of Webkit.
  • user3167101
    user3167101 over 9 years
    Why not just !! if you want a Boolean?
  • Marc-André Lafortune
    Marc-André Lafortune about 9 years
    Shouldn't the false be true?
  • Jon z
    Jon z about 9 years
    document.contains(someReferenceToADomElement); what a revelation!!! the answer is so long, I wish it would just highlight that one line of code.
  • user3167101
    user3167101 about 9 years
    @Jonz Removed the old answer part, don't forget to go and vote up csuwldcat
  • Jon z
    Jon z about 9 years
    This is indeed the best answer: - it's a web standard - it's very well supported (somewhat surprisingly it doesn't appear in Firefox until version 9, I'm guessing because it was a non-standard function invented in IE that wasn't standardized until later) - it must be the fastest because it uses a single call to a native API
  • Edward
    Edward over 8 years
    This answer works well, but only when the element has an id. The better solution that answers the question How to check if element exists in the visible DOM? with any element, even elements without ids is to do document.body.contains(element).
  • Lee Saxon
    Lee Saxon over 8 years
    Can/Should this be used to target specific elements via class or ID? What's the syntax?
  • user3167101
    user3167101 over 8 years
    @Edward This is something completely different to contains()
  • Edward
    Edward over 8 years
    I get that. I was just suggesting in my comment that other answers are better and more suited to the question.
  • user3167101
    user3167101 almost 8 years
    Why is $('#elementId')[0] something to be avoided?
  • ShapCyber
    ShapCyber almost 8 years
    Testing the above code I got this error " Expected '===' and instead saw '==' "
  • Broda Noel
    Broda Noel almost 8 years
    This won't check the visible DOM. Will check all the DOM
  • launchoverit
    launchoverit over 7 years
    Just wanted to second crush's comment about browser support. According to MDN, none of IE supports document.contains(). In addition to linking to @csuwildcat's answer, could we just replace the suggestion with document.body.contains()? developer.mozilla.org/en-US/docs/Web/API/Document
  • Black
    Black over 7 years
    Which method is faster? Did anyone tested it yet?
  • daiscog
    daiscog over 7 years
    If the node IS the document.body, surely the method should return true? I.e., return (node === document.body) || document.body.contains(node);
  • Longblog
    Longblog almost 7 years
    You don't need the >0, since length is false. Be aware, sometimes a browser will throw a "can't find length of undefined" error, depending on how you write this.
  • Zameer Fouzan
    Zameer Fouzan over 6 years
    plus 1 for !! part. could you explain or give ref link to its explanation ?
  • eduardo a
    eduardo a over 6 years
    @LeeSaxon The syntaxis is document.body.contains([selector]), i.e. document.body.contains(document.getElementById('div')
  • Code Buster
    Code Buster about 6 years
    Been long I answered this, So, using $('#elementId')[0] I believe you are always indicating that the value will be at the 0th index. This way you are always checking for the 1st occuring element. What is there were multiple checkboxes with same name, so like a radio button. That time the .length will be helpful.
  • user3167101
    user3167101 about 6 years
    @ShapCyber Sounds like a linting rule you have
  • Ian Davis
    Ian Davis almost 6 years
    Careful as this will throw the following error if the element is not in the document: Cannot read property 'baseURI' of null. Example: console.log(document.querySelector('aside').baseURI)
  • Steven Vachon
    Steven Vachon almost 5 years
    So, if the element doesn't have an id, then it's considered to be not in the DOM? I'd say this is wrong.
  • Steven Vachon
    Steven Vachon almost 5 years
  • Steven Vachon
    Steven Vachon almost 5 years
    This might be the best answer as it does not cause any re-rendering in the DOM.
  • Marc K.
    Marc K. over 4 years
    What about Node.isConnected() link
  • csuwldcat
    csuwldcat over 4 years
    @MarcK. that API didn't exist when I first added this answer, but the other issue is that Node.isConnected() isn't compatible with IE and old non-Chromium Edge, so I think we're still going to need to use body.contains() into the foreseeable future.
  • Kagami Sascha Rosylight
    Kagami Sascha Rosylight over 4 years
    This method can't be used as it always prints the same string as of now.
  • Peter Mortensen
    Peter Mortensen over 4 years
    An explanation would be in order (respond by editing your answer, not here in comments).
  • Peter Mortensen
    Peter Mortensen over 4 years
    In all what? All cases?
  • Peter Mortensen
    Peter Mortensen over 4 years
    Is it always "HTML"? Could it be "html"?
  • Yunus
    Yunus about 4 years
    x.tagName or x.nodeName always in uppercase no mater how you write it in your code
  • Don Cullen
    Don Cullen about 4 years
    For @ZameerFouzan and those wondering about !!, it's done like this: var elementExists = !!document.getElementById("find-me"); In that case, it'll return boolean value based on whether the element exists or not.
  • lakam99
    lakam99 almost 4 years
    Simplest solution... Easier than document.body.contains.
  • Mustapha-Belkacim
    Mustapha-Belkacim almost 4 years
    alex you're right document.contains() is enough if you want to check the entire DOM, but to check the visible DOM as the question is originally asking .body is necessary
  • Andrii
    Andrii almost 4 years
    For Type Script shoud be if(document.getElementById("myElementId").lenght>0)
  • AGamePlayer
    AGamePlayer almost 4 years
    Need a try catch for this method.
  • Eric
    Eric over 3 years
    @kayahr on what conditions may an element is in the visible DOM but the parent node is not connected to it?
  • kayahr
    kayahr about 3 years
    @Eric An element which has no parent node can't be connected to the document , that's right. But on the other hand when element has a parent node then this does NOT automatically mean that the element is connected to the document because the parent node may be disconnected and this means all child elements are also disconnected. So this check is wrong and does not do what it says.
  • CWarrington
    CWarrington over 2 years
    document.body.contains worked for me. Thanks
  • daformat
    daformat over 2 years
    These methods don't work should your element be within a shadow DOM, trying to find a way to make it work in this scenario: the best I can think of would be to check for an offsetWidth or any other layout related property. It would prevent 0 sized elements from being detected though, so it's far from bulletproof
  • daformat
    daformat over 2 years
    See @Robbendebiene answer for a working method with shadow DOMs: stackoverflow.com/a/62300560/1358317
  • Blaze612 YT
    Blaze612 YT almost 2 years
    17 upvotes. My most ever!