This question already has answers here:
How can I check if an element exists in the visible DOM?
(27 answers)
Closed 8 years ago.
The question is quite straightforward. Is there a javascript only (no jQuery/other library pls) method of checking if an element created via javascript exists?
For instance, if I did this:
var foo=document.createElement("div");
document.getElementById("bar").appendChild(foo);
Would there be a way to check if foo already exists?
You could simply get the element by id and see if its not null.
var foo=document.createElement("div");
document.getElementById("bar").appendChild(foo);
foo.setAttribute("id","foo");
var ele = document.getElementById("foo");
if(ele !== null){ alert("Hi");}
foo is not an element, it's a variable whose value is an element. There are different ways to interpret your question.
Is the value of the variable foo a DOM element?
If you want to check if the variable foo exists and has as its value an element, you can say
foo && typeof foo === 'object' && foo.nodeType
or something similar. This will check whether the element is any kind of Node. To check for an element, use foo.nodeType === Node.ELEMENT_NODE.
Is a particular HTML element in the DOM?
If you want to check if the element held in variable foo is in the DOM, as opposed to having been created, but not yet inserted, then:
foo.baseURI
since baseURI is set only upon DOM insertion. You might think you could check parentNode, which is also not set until DOM insertion, but children of the non-inserted element, if any, will report a parentNode, as will elements appended to a document fragment.
The other alternative is to use Node#contains:
document.body.contains(foo)
which essentially does the same thing as scanning the entire DOM for the element:
Array.prototype.some.call(document.querySelector('*'), function(elt) {
return elt === foo;
})
In any case, this all seems pointless, because as far as I can imagine, if you hold a reference to a DOM element, and it's not not in the DOM, then it is in the DOM.
Is there already an element in the place I'm going to be inserting this one?
If you know where the element is going to go, in this case as a child of bar, and that's enough to convince you that the "element already exists", you can check easily enough with something like:
document.getElementById("bar").children.length > 0
Is there already an element with this ID?
As other commenters and responders have noted, you can obviously find an element in the DOM if you have arranged to provide it with some uniquely identifiable characteristics, most likely an id.
I hope it's obvious that element ID is completely separate from the name of any JavaScript variables which happen to be holding references to that element. It is true that elements become available on the root (window) object under their ID or name attributes, a feature best left unused.
Was the element in the source HTML, or created by JavaScript?
From the wording of your question, it seems that you might be interested in whether the element was created by JS, as opposed to originating from the source HTML. There is no way I know of to detect that. If you are intent on doing so, override document.createElement as follows:
document.createElement = (function() {
var old = document.createElement;
return function(tagName) {
var elt = old.call(document, tagName);
elt.I_CREATED_THIS = true;
return elt;
};
}());
> document.body.I_CREATED_THIS
undefined
> elt = document.createElement('span');
> elt.I_CREATED_THIS
true
Related
I am kinda newbie and I really want to understand why the variables we create don't just get the values inside the DOM element, but becomes the DOM element?
Here is some basic code;
var elementValues = document.getElementById("p1");
elementValues.style.color = "red";
// I don't understand why we don't need this step in order to manipulate the DOM.
// document.getElementById.getElementById("p1") = elementValues;
Aren't we basically saying to copy the values from DOM element with an id of p1 and paste them into elementValues?
But why the color of DOM element changes when I change the color of elementValues? From what I understand it acts like a pointer.
In Javascript, Object variables store a reference to the objects. Hence, document.getElementById returns a reference. So when you modify the values of elementsValues, your are editing the referenced object.
Have a look on Working with Objects - Comparing Object. You could read the whole page also to have an overview.
Yes, it is like a pointer.
By using var elementValues = document.getElementById("p1"); you are assigning a reference to the DOM element to the variable. Nothing about the element gets saved to the variable, but "where to find it".
I apologize if this is an easy question! I'm pretty new to javascript.
I'm trying to check if a div has a specific child element (I'll name it 'child2'). I know about .hasChildNodes() but as far as I know it only lets you know if child nodes exist. I tried .contains like so:
if (parentDiv.contains(child2) == false) {
but even if the parentDiv does contain child2, it still returns false. It seems like such a simple thing to do and I've been trying to search around but I haven't had any luck in pure js. Thanks!
You can use querySelector():
var hasChild = parentDiv.querySelector("#child2") != null;
The querySelector() method lets you search the subtree beneath the starting element using the given CSS selector string. If the element is found, its DOM node is returned.
This question already has answers here:
Find an element in DOM based on an attribute value
(11 answers)
Closed 8 years ago.
I am looking for a method like document.getElementsByClassName(), but just for attributes, that would also mean that document.getElementsByAttributeValue("class", "testclass") would have the same output as document.getElementsByClassName("testclass").
It is not that easy since you cannot just add a function like this
document.getElementsByAttributeValue = function(){....};
because it has to work for document.getElementById("foo").getElementsByAttributeValue(...) as well.
Needless to say, that I don't want a JQuery solution because there is no need for a giant library for just one function.
The function I created and the implementation looks like this:
Node.prototype.getElementsByAttributeValue = function(attribute, value){
var dom = this.all || this.getElementsByTagName("*");
var match = new Array();
for (var i in dom) {
if ((typeof dom[i]) === "object"){
if (dom[i].getAttribute(attribute) === value){
match.push(dom[i]);
}
}
}
return match;
};
I wanted the function to work within every html element and in the html document as well, so I added the function to the parent class of all html subclasses, the Node class.
There is a nice visualisation of JavaScript objects.
With this.all || this.getElementsByTagName("*") I took all the html elements within the object which called the function. Then I looped through all the elements I took and checked if they had the right attribute values and if they had, I pushed them into the match array
You can use JQuery to easily get all the elements with a particular class as follows:
$('[class~="d1"]')
This will select the elements with class containing d1
Check Demo
For more: Read JQuery selector
I keep learning very simple things about functions, returns, id and everything, so I ran into another problem that looks simple, but I cannot understand why it happens. Check this code:
function test() {
var text = document.createTextNode("Hello");
text.id = "t";
}
var whatIjustwrote = window.document.getElementById("t");
alert(whatIjustwrote);
Does the getElementById has restrictions to look only for global items? What would be the way to make that alert output the text node inside the function?
Thank you for any comment. The last few days asking things here I have been learning quite a lot!
JSFiddle
Firstly, getElementById will only return an element, and you're creating a text node.
Secondly, it will only return an element that has been added to the DOM. The node you create doesn't get added to the DOM, so it wouldn't be found even if it could be.
Finally, you don't actually call the test function, so the text node isn't even created in memory.
Here's an updated fiddle that demonstrates getElementById actually working:
function test() {
var text = document.createElement("span"); //Create an element
text.innerHTML = "Hello";
text.id = "t";
document.body.appendChild(text); //Add it to the DOM
}
test(); //Invoke the function (so the element actually gets created)
var yourElement = document.getElementById("t"); //Get reference to element
getElementById does only search for element nodes. You did create a text node, which has neither attributes nor an id - you just added a custom property to the JS object. Also, you did not append your node to the document, so it couldn't have been found in the DOM tree.
You might want to read an introduction to the DOM (at MDN), the introduction at quirksmode.org or even the W3 standard itself (especially the introduction section)
function test() {
var elem = document.createElement("span"); // Create an element
var text = document.createTextNode("Hello"); // Create a textnode
elem.appendChild(text); // add text to the element
elem.id = "t"; // assign id to the element
document.body.appendChild(elem); // Add it to the DOM
}
test();
var yourElement = document.getElementById("t"); // Get the element from the DOM
alert(yourElement.textContent); // alerts "Hello"
// you also could have alerted yourElement.firstChild.data - the content of the
// textnode, but only if you had known that yourelement really has a firstchild
(Demo at jsfiddle.net)
A couple of points that come to mind..
1) You cant give a textNode an id attribute (you're actually giving it a new member variable named id)
2) To find an element it must exist in the document's DOM
Do this instead:
var mSpan = document.createElement('span');
mSpan.id = 't';
mSpan.appendChild( document.createTextNode('Hello') );
document.body.appendChild(mSpan);
var whatIjustwrote = window.document.getElementById("t");
alert(whatIjustwrote.innerText);
Does the getElementById has restrictions to look only for global
items?
The answer is no. First you have to define global items anyways. Anything that is attached to the DOM is in fact global, and in terms of global javascript objects there is only one, window, in the case of a browser. You are creating a function but you're never executing it.
In addition the text node cannot actually have an id or any other attribute. You need an element for this, so even if you execute the function you would still get null. Also creating a node does not attach is to the DOM, so you won't be able to access it even if this isn't a text node.
I have updated your fiddle.
As far as I know document.getElementById('myId') will only look for HTML elements that are already in the document. Let's say I've created a new element via JS, but that I haven't appended it yet to the document body, is there's a way I can access this element by its id like I would normally do with getElementById?
var newElement = document.createElement('div');
newElement.id = 'myId';
// Without doing: document.body.appendChild(newElement);
var elmt = document.getElementById('myId'); // won't work
Is there a workaround for that?
(I must tell that I don't want to store any reference to this particular element, that's why I need to access it via its Id)
Thank you!
If it isn't part of the document, then you can't grab it using document.getElementById. getElementById does a DOM lookup, so the element must be in the tree to be found. If you create a floating DOM element, it merely exists in memory, and isn't accessible from the DOM. It has to be added to the DOM to be visible.
If you need to reference the element later, simply pass the reference to another function--all objects in JavaScript are passed by reference, so working on that floating DOM element from within another function modifies the original, not a copy.
For anyone stumbling upon this issue in or after 2019, here is an updated answer.
The accepted answer from Andrew Noyes is correct in that document.getElementById won't work unless the element exists in the document and the above code already contains a reference to the desired element anyway.
However, if you can't otherwise retrieve a direct reference to your desired element, consider using selectors. Selectors allow you to retrieve nodes that aren't necessarily in the DOM by using their relationship to other nodes, for example:
var child = document.createElement("div");
child.id = "my_id";
var parent = document.createElement("div");
parent.appendChild(child);
var child2 = parent.querySelector("#my_id");
getElementById is a method on the document object. It's not going to return anything not in the document.
On not storing a reference, huh? If you could magically pull it out of the air by id, then the air would be a reference to it.
If you've created it, just pass the object to other functions and access it directly?
function createDiv()
{
var newElement = document.createElement('div');
doWorkWithDiv(newElement);
}
function doWorkWithDiv(element)
{
element.className = 'newElementCSS';
element.innerHTML = 'Text inside newElement';
addToDoc(element);
}
function addToDoc(element)
{
document.body.appendChild(element);
}