在纯JavaScript中获取元素的第n个子编号

时间:2014-06-26 17:08:29

标签: javascript html css-selectors

我正在为我的网站创建一个函数,我在其中设置了一个数据属性,其中包含该元素的第n个子编号。

我的HTML标记:

<html>
<body>
    <section class="hardware">some text, nth-child is one</section>
    <section class="hardware">some text, nth-child is two</section>
    <section class="hardware">some text, nth-child is three</section>
    <section class="hardware">some text, nth-child is four</section>
    <section class="hardware">some text, nth-child is five</section>
</body>
</html>

到目前为止我的JavaScript:

var selector = document.getElementsByClassName('hardware');
for(var i = 0; i <= selector.length; i++) {
    var index = selector[i] //get the nth-child number here
    selector[i].dataset.number = index;
}

如何使用纯JavaScript(而不是jQuery)获取元素的第n个子编号,这在JavaScript中是否可行?

5 个答案:

答案 0 :(得分:5)

查看之前的答案HERE

使用

var i = 0;
while( (child = child.previousSibling) != null ) 
  i++;
//at the end i will contain the index.

答案 1 :(得分:3)

当你说“数字”时,你的意思是1,2等,还是“一个”,“两个”等?

如果是1,2等,则数字只是i + 1 ...

如果“one”,“two”等,那么你需要在元素中获取文本,然后可能使用Regexp来解析它并获得你想要的值。

答案 2 :(得分:2)

简单地线性递增索引只有在 all 匹配该类名的元素是同一父级的唯一子元素时才有效,没有其他元素可能会干扰:nth-child(),正如给定标记中所示。有关其他元素可能会如何干扰的说明,请参阅this answer。另请查看:nth-child()上的Selectors spec

实现这一目标更简单的一种方法是循环遍历每个元素的父节点的子节点,为每个作为元素节点的子节点递增计数器(因为:nth-child()仅计算元素节点):

var selector = document.getElementsByClassName('hardware');

for (var i = 0; i < selector.length; i++) {
    var element = selector[i];
    var child = element.parentNode.firstChild;
    var index = 0;

    while (true) {
        if (child.nodeType === Node.ELEMENT_NODE) {
            index++;
        }

        if (child === element || !child.nextSibling) {
            break;
        }

        child = child.nextSibling;
    }

    element.dataset.number = index;
}

JSFiddle demo

请注意,这将应用正确的索引,无论DOM中的给定元素位于何处

  • 如果特定section.hardware元素是不同section的第一个也是唯一的子元素,则会为其指定正确的索引1.

  • 如果.hardware元素是其父元素的第二个子元素,即使它是唯一一个具有该类的元素(即它跟随其他元素没有类) ,它将被分配正确的索引2。

答案 3 :(得分:2)

我将用以下假设回答问题:

  • 您的hardware分类元素都是兄弟姐妹
  • 您对第n个孩子不是第n个孩子+ 1
  • 感兴趣
  • 他们可以与其他元素混合使用:
<body>
    <section class="hardware">some text, nth-child is zero</section>
    <section class="software"></section>
    <section class="hardware">some text, nth-child is two</section>
</body>

(我做出这些假设,因为这是我面临的问题,认为它可能有用)

所以主要区别在于,我不是要查询属于给定类的元素,而是要获取body的(直接)子元素,并过滤它们。

Array.from(document.body.children)
  .map((element, index) => ({element, index}))
  .filter(({element}) => element.classList.contains('hardware'))

结果数组如下所示:

[
  {element: section.hardware, index: 0}
  {element: section.hardware, index: 2}
]

答案 4 :(得分:0)

您可以在空格处拆分文本,从每个拆分阵列中获取最后一个

var hards = document.getElementsByClassName('hardware');
for (var i=0; i < hards.length; i++) {
    var hardText = hards[i].innerText || hard[i].textContent;
    var hardList = hardText.split(' ');
    var hardLast = hardList[hardList.length - 1];
    alert(hardLast);
}

我正在使用||这里因为Firefox不支持innerText,而IE不支持textContent

如果元素只包含文字,则可以使用innerHTML代替innerText/textContent