Why does firstChild not return the first element?

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?

Answers:

Answer

The 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;
Answer

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.

Answer
  1. There isn't a getElementByClass method, this is why you failed. Open console and you'll see JS error. I guess what you thought were getElementsByClassName. Note it's in plural form, and it returns an array-like.

  2. 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 is firstElementChild. 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.

Answer

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...

Answer

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.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.