最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why does firstChild not return the first element? - Stack Overflow

programmeradmin0浏览0评论

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
  • there are empty text nodes before and after the image. you can fix html by removing whitespace between tags. --> <div><img /></div> – WhiteHat Commented Dec 4, 2015 at 19:33
  • @WhiteHat I did try that, but I forgot to mention it in the question. The div 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:06
  • @RonitJoshi Well, then let's just redefine the way the DOM has worked for decades so it doesn't seem ridiculous to you. White space is white space and must be represented. It's represented as a node. If you're interested in elements instead of nodes, you already found there is an entire set of APIs for that (such as firstElementChild)--use them. MDN docs on firstChild 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
  • I'm voting to close this question as off-topic because it is asking about behavior which is clearly described in the documentation. – user663031 Commented Dec 6, 2015 at 4:42
Add a comment  | 

5 Answers 5

Reset to default 8

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;

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.

  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.

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.

发布评论

评论列表(0)

  1. 暂无评论