如何选择父元素的第一个子元素?

4

我正在尝试使用纯JavaScript选择父元素的第一个子元素,并更改其中一些CSS属性。我已经尝试了.firstChild.childNodes[1]方法,但它们都不起作用。可以使用CSS nth-child()选择器来完成此操作,但我希望使用JavaScript以获得更好的浏览器支持。

示例:

HTML

    <div class="daddy">
       <div class="child">I want select this child and change it's css property.</div>
       <div class="child"></div>
       <div class="child"></div>
       <div class="child"></div>
    </div>

我尝试过:

JavaScript

    var x = document.getElementsByClassName('daddy');
    var d = x.firstChild; // and the x.childNodes[1]
    d.style.width="5em";

What works:

CSS

   daddy:nth-child(1) { width: 5em; }

非常感谢您的帮助。


你尝试过使用.daddy .child:first-child { width: 5em; }吗?因为这在每个浏览器中都被支持(尽管只有IE从版本7开始支持)。 - David Thomas
是的,我有这个并且它可以工作,但我想要只用JavaScript来完成。 - basitmate
5个回答

7

两个问题:

  1. getElementsByClassName 返回一个类似数组的对象。您需要选择列表中的第一个元素。
  2. firstChildchildNodes 将返回文本节点,而不仅仅是元素。使用 .children 来仅访问元素:

var x = document.getElementsByClassName('daddy');
var d = x[0].children[0];
d.style.width="5em";
<div class="daddy">
  <div class="child">I want to select this child and change its css property.</div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>


谢谢,但我可以使用document.getElementById()代替document.getElementsByClassName()吗?下面的代码还能用吗? - basitmate
如果您的容器一个ID,那么是的 - 但在这种情况下,您将获得一个单独的元素(而不是列表),因此它将是var d = x.children [0]; - Paul Roub

2
var x = document.getElementsByClassName('daddy');
var d = x[0].children[0];
d.style.width = '5em';

或者如果你有多个父元素,你可以这样做:
var x = document.getElementsByClassName('daddy');

[].forEach.call(x, function(d) {
    d.children[0].style.width = '5em';
});

1

如果您需要更好的浏览器支持,您可以使用纯CSS,通过使用:first-child选择器,因为它是跨浏览器且符合CSS 2.1标准。请参见此链接here和下面的表格,该表格说明了浏览器的支持情况:

table first-child

所以这里有一段只使用CSS的代码片段:

.child:first-child {
  /*whatever CSS you want here --
  just fot visualization and snippet :*/
  background-color: red;
  color: white;
}
<div class="daddy">
  <div class="child">I want select this child and change it's css property.</div>
  <div class="child">child 2</div>
  <div class="child">child 3</div>
  <div class="child">child 4</div>
</div>


是的,我知道:first-child可以很好地工作,但如果我只想使用JavaScript来完成这个任务呢? - basitmate
为什么你要使用JS,而不是像我的答案一样只使用CSS,这样会更简单/更清晰呢? - dippas
我同意并将使用:first-child,但我只是好奇是否可以用Js完成这个操作。 - basitmate
你已经有了一些只使用JS的答案..但是既然你要使用:first-child,那么能不能把我的答案标记为已采纳呢? - dippas
1
当然可以。我想问一下,如果我将您的答案标记为已接受,对您有什么好处呢?我是新来的。 - basitmate
这只会增加我的SO声誉,但我之所以这么说是因为你告诉我我们将使用我的答案,通常OP会标记解决问题的答案或者OP将在代码中使用的答案作为已接受的答案;) - dippas

0

getElementsByClassName 返回一个 nodeList,它没有 firstChildchildNodes 属性,你应该获取集合中的元素,然后使用这些属性,例如 x[index]

var x = document.getElementsByClassName('daddy'), i = 0, j;

for (; i < x.length; i++) {
    e = x[i].childNodes;
    for (j = 0; j < e.length; j++) {
        if (e[j].nodeType === 1) {
            e[j].style.width = '5em';
            break;
        }
    }
}

请注意,只有较新的浏览器(包括IE9)支持getElementsByClassName方法。如果您想要支持旧版本的浏览器,您应该使用shim方法或者使用其他替代函数。这个问题的答案提供了几种解决方案。
作为另一种选择,您也可以使用querySelectorAll方法:
[].slice.call(document.querySelectorAll('.daddy > .child:first-child'))
        .forEach(function(e) {
            e.style.width = '5em';
        });

-2

这与问题有什么关系?OP并不想完善CSS选择器,也没有在问题中使用.daddy .child - Paul Roub
所有.child元素都是.daddy元素的直接子元素;这对于查找(仅)第一个子元素没有任何帮助。 - David Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接