web-dev-qa-db-ja.com

純粋なJavaScriptで要素のn番目の子の番号を取得する

私は、その要素の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でも可能ですか?

16
Sake Salverda

「数字」と言うとき、1、2など、または「1」、「2」などを意味しますか?

1、2などの場合、番号は単にi + 1 ...

「1」、「2」などの場合、要素内のテキストを取得する必要があります。その後、おそらく正規表現を使用して解析し、必要な値を取得します。

4
jcaron

この以前の回答を確認してください [〜#〜] here [〜#〜]

それは使用しています

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

allがそのクラス名に一致する要素が同じ親の唯一の要素の子であり、:nth-child()に干渉する可能性のある他の要素がない場合にのみ、インデックスを線形にインクリメントします指定されたマークアップで正確に表示されます。他の要素がどのように干渉するかについての説明は この回答 をご覧ください。 :nth-child()の-​​ セレクター仕様 も確認してください。

これを実現するより確実な方法の1つは、各要素の親ノードの子ノードをループして、要素ノードである各子ノードのカウンターをインクリメントすることです(: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デモ

これにより、正しいインデックスが適用されることに注意してください指定された要素がDOMのどこにあるかに関係なく

  • 特定のsection.hardware要素は、異なるsectionの最初で唯一の子であり、正しいインデックス1が割り当てられます。

  • もし .hardware要素は親の2番目の子であり、そのクラスを持つ唯一の子であっても(つまり、他の要素withoutクラスに続く場合)、正しいインデックス2が割り当てられます。

2
BoltClock

以下の前提で質問に答えます。

  • hardwareクラスの要素はすべて兄弟です
  • N番目の子+ 1ではなくn番目の子に興味がある
  • それらは他の要素と混合できます:
<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}
]
2
fodma1

各分割配列から最後のWordを取得するときに、スペースでテキストを分割できます。

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を使用できます。

0
Andy G