Получить элемент nth-child number в чистом JavaScript

Я создаю функцию для своего сайта, где я устанавливаю атрибут data, который содержит nth-child число этого элемента.

Моя разметка 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;
}

Как я могу получить число nth-child элемента с чистым JavaScript (а не jQuery), возможно ли это в JavaScript?

Ответ 1

Когда вы говорите "число", вы имеете в виду 1, 2 и т.д. или "один", "два" и т.д.

Если 1, 2 и т.д., то число просто я + 1...

Если "один", "два" и т.д., то вам нужно получить текст внутри элемента, а затем, вероятно, используйте Regexp для его анализа и получения требуемого значения.

Ответ 2

Проверьте этот предыдущий ответ ЗДЕСЬ.

Он использует

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

Ответ 3

Простое увеличение индекса линейно будет работать, только если все элементы, соответствующие этому имени класса, являются единственными дочерними элементами одного и того же родителя, без каких-либо других элементов, которые могут помешать :nth-child(), как показано в точности в данной разметке. См. этот ответ для объяснения того, как другие элементы могут вмешиваться. Также просмотрите Specors spec на :nth-child().

Одним из способов достижения этого, более надежным является прохождение дочерних узлов каждого родительского элемента node, приращение счетчика для каждого дочернего элемента node, который является элементом node (так как :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.

Ответ 4

Вы можете разделить текст на пробелы, чтобы получить последнее слово из каждого разделенного массива:

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.

Если элементы содержат только текст, то вместо innerText/textContent можно использовать innerHTML.