I was writing some code the other day, and for some reason, I had no idea why this happened, but this was part of the code that I had written.
var item = document.getElementByClass('object');
var innerImageId = item.firstChild.id;
I went over this code a lot of times. The problem of this code is that the value of innerImageId is undefined. The firstChild of item is an image. I need to get the id of the image, but no matter how many times I went over the code, it did not work. Here is the HTML file of the code.
<div class="object inventory-box">
<img src="image.png" id="sample-image">
</div>
Doesn't this seem correct? Well, I did some debugging in Google Chrome, and it turns out that there are 3 nodes in the div "object". The id of the first and the last node was undefined, but the 2nd one was "sample-image". I then tried "firstElementChild" instead of "firstChild", and this worked well.
Then just to test it out, I did something like this-
<div class="object inventory-box">
<img src="image.png" id="sample-image">
</div>
(or with multiple lines of unnecessary whitespace)
but it still shows 3 nodes, the enter symbol, the div, and another enter symbol. This problem keeps occurring in Chrome, Internet Explorer and Firefox.
Can someone please explain why there are these random 2 extra nodes?
I was writing some code the other day, and for some reason, I had no idea why this happened, but this was part of the code that I had written.
var item = document.getElementByClass('object');
var innerImageId = item.firstChild.id;
I went over this code a lot of times. The problem of this code is that the value of innerImageId is undefined. The firstChild of item is an image. I need to get the id of the image, but no matter how many times I went over the code, it did not work. Here is the HTML file of the code.
<div class="object inventory-box">
<img src="image.png" id="sample-image">
</div>
Doesn't this seem correct? Well, I did some debugging in Google Chrome, and it turns out that there are 3 nodes in the div "object". The id of the first and the last node was undefined, but the 2nd one was "sample-image". I then tried "firstElementChild" instead of "firstChild", and this worked well.
Then just to test it out, I did something like this-
<div class="object inventory-box">
<img src="image.png" id="sample-image">
</div>
(or with multiple lines of unnecessary whitespace)
but it still shows 3 nodes, the enter symbol, the div, and another enter symbol. This problem keeps occurring in Chrome, Internet Explorer and Firefox.
Can someone please explain why there are these random 2 extra nodes?
Share Improve this question edited Dec 6, 2015 at 4:39 user663031 asked Dec 4, 2015 at 19:27 Ronit JoshiRonit Joshi 671 silver badge5 bronze badges 4 |5 Answers
Reset to default 8The browser insert a text node when there are white spaces or new lines in your code. You are targeting one of those.
Try
var img = document.querySelector('.object img');
var innerImageId = img.id;
You can also use firstElementChild
in place of firstChild
which will skip those empty text nodes.
EDIT: Blah thanks BAM5 just not paying attention as I typed.
There isn't a
getElementByClass
method, this is why you failed. Open console and you'll see JS error. I guess what you thought weregetElementsByClassName
. Note it's in plural form, and it returns an array-like.Even if you get over the first issue, you may still fail due to your markup.
firstChild
does return the first one among children, including the text nodes. Your better choice isfirstElementChild
. Or you have to write like this to avoid text node children:<div><img></div>
So, this should give what you wanted:
var items = document.getElementsByClassName('object');
var innerImageId = items[0].firstElementChild.id;
On the other hand, other answers pointed that querySelector
can do the job, indeed. And it has a brother querySelectorAll
. You could search MDN for their usages and slight difference in between.
Use firstElementChild
instead of firstChild
. As l. Catallo said, you may be getting a text node instead of an element.
Looks like Atheist beat me to it, but in his answer he incorrectly used firstChildElement
. Would comment, but not enough rep...
I faced a similar question while I was learning DOM exploration and I observed that, when there is a space or the next tag is on the next line, the node list normally shows a text node. For Example: If I wrote my HTML code as below, and tried to get all the child nodes of the element body.
HTML Code:
<body>
<h2> Lets Study DOM!! </h2>
<input type = 'text' id = 'topic'> </input></br>
<button onClick = addToList()> Click Me to Add </button>
Javascript:
console.log(document.querySelector('body').childNodes);
The above code gave me the following output:
[text, h2, text, input#topic, text, br, text, button, text, ul#unordered, text, script]
On the other hand, if I modified my code as shown below, and then tried to print the node list, I got a different output as shown below:
HTML Code:
<body><h2> Lets Study DOM!! </h2>
<input type = 'text' id = 'topic'> </input></br>
<button onClick = addToList()> Click Me to Add </button>
Javascript:
console.log(document.querySelector('body').childNodes);
The above code gave me the following output:
[h2, text, input#topic, text, br, text, button, text, ul#unordered, text, script]
So clearly, the browser considers the space after the body tag as a text node.
<div><img /></div>
– WhiteHat Commented Dec 4, 2015 at 19:33div
really should still have one node, because it is just ridiculous to have that in a browser. – Ronit Joshi Commented Dec 5, 2015 at 1:06firstElementChild
)--use them. MDN docs onfirstChild
explain the problem quite clearly. Also, please edit your questions more carefully.var item = document.getElementByClass('object');
would have immediately stopped the interpreter since their is no such API. – user663031 Commented Dec 6, 2015 at 4:29