How do you test an element for existence without the use of the getElementById
method? I have setup 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 what the above code demonstrates is an element being stored into a variable and then removed from 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.
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...This is spec'd 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 itslength
property, because aNodeList
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...
I simply do:
Works for me and had no issues with it yet....
I liked this approach
Also
You can also use
jQuery.contains
, which checks if an element is a descendant of another element. I passed indocument
as the parent element to search because any elements that exist on the page DOM are a descendant ofdocument
.Use
querySelectorAll
withforEach
:as the opposite to:
csuwldcat's solution seems to be the best of the bunch, but a slight modification is needed to make it work correctly with an element that's in a different document than the javascript is running in, such as an iframe:
YOUR_ELEMENT.ownerDocument.body.contains(YOUR_ELEMENT);
Note the use of the element's
ownerDocument
property, as opposed to just plain ol'document
(which may or may not refer to the element's owner document).torazaburo posted an even simpler method that also works with non-local elements, but unfortunately, it uses the
baseURI
property, which is not uniformly implemented across browsers at this time (I could only get it to work in the webkit-based ones). I couldn't find any other element or node properties that could be used in a similar fashion, so I think for the time being the above solution is as good as it gets.