親に相対的な子として要素のインデックスを取得します


160

私がこのマークアップを持っているとしましょう:

<ul id="wizard">
    <li>Step 1</li>
    <li>Step 2</li>
</ul>

そして私はこのjQueryを持っています:

$("#wizard li").click(function () {
    // alert index of li relative to ul parent
});

liそれをクリックしたときに、親を基準にした子のインデックスを取得するにはどうすればよいliですか?

たとえば、「ステップ1」をクリックするalertと、「0」付きのポップアップが表示されます。

回答:


247
$("#wizard li").click(function () {
    console.log( $(this).index() );
});

ただし、リストアイテムごとに1つのクリックハンドラーをアタッチするよりも(パフォーマンスに関して)次のように使用する方が適切ですdelegate

$("#wizard").delegate('li', 'click', function () {
    console.log( $(this).index() );
});

jQuery 1.7以降では、を使用する必要がありますon。以下の例は、イベントを#wizard要素にバインドし、デリゲートイベントのように機能します。

$("#wizard").on("click", "li", function() {
    console.log( $(this).index() );
});

3
こんにちはredsquare ..私はjQueryを使って練習しています。デリゲート:Dについてちょっとn00bです。なぜ、デリゲートが要素に直接イベントをアタッチするよりも優れているのですか?
stecb

1
@steweb-こんにちは-潜在的に多くのイベントハンドラよりも1つのイベントハンドラの方がはるかに望ましいため 大きなリストがある場合、domにイベントをアタッチすると負荷が高くなる可能性があるため、原則として、各要素の個々のハンドラーではなく、可能な限り上記を使用するようにします。より深く掘り下げた記事の1つはbriancrescimanno.com/2008/05/19/…です。また、google 'javascript event delegation'
redsquare

わかりましたので、この方法でイベントを管理することは、従来の「domアタッチメント」よりも軽いものです:) ..ありがとう!
stecb

@steweb-jqueryはすべてのli要素の初期ルックアップを行う必要がないため、軽量化にもなります。コンテナをルックアップし、そのレベルでリッスンして、クリックされたオブジェクトがliかどうかを確認します。
redsquare

この.indexメソッドは私にとって非常に役に立ちます。jQuery Sortableを使用してソートを行っていますが、セマンティックランキング情報をDOMに保存しています。.index()を使用すると、DOMからランクを本当にきれいに引き戻すことができます。ありがとう!
SimplGy 2013年

41

何かのようなもの:

$("ul#wizard li").click(function () {
  var index = $("ul#wizard li").index(this);
  alert("index is: " + index)
});

9
素晴らしい追加-親セレクターに相対的なインデックスを見つけることができます。+1
BasTaller 2012

1
この答えは、例として考えられる解決策ではなく実際に質問に答えるため、この答えを好む
DarkMukke

8

この例を見てください。

$("#wizard li").click(function () {
    alert($(this).index()); // alert index of li relative to ul parent
});

4

必要がなければ、これを実現するためにjQueryのような大きなライブラリを必要とする必要はありません。組み込みのDOM操作でこれを実現するにliは、配列内の兄弟のコレクションを取得しindexOf、クリックすると、その配列内のクリックされた要素を確認します。

const lis = [...document.querySelectorAll('#wizard > li')];
lis.forEach((li) => {
  li.addEventListener('click', () => {
    const index = lis.indexOf(li);
    console.log(index);
  });
});
<ul id="wizard">
    <li>Step 1</li>
    <li>Step 2</li>
</ul>

または、イベント委任を使用します。

const lis = [...document.querySelectorAll('#wizard li')];
document.querySelector('#wizard').addEventListener('click', ({ target }) => {
  // Make sure the clicked element is a <li> which is a child of wizard:
  if (!target.matches('#wizard > li')) return;
  
  const index = lis.indexOf(target);
  console.log(index);
});
<ul id="wizard">
    <li>Step 1</li>
    <li>Step 2</li>
</ul>

または、子要素が(todoリストのように)動的に変化する可能性がある場合liは、事前にではなく、クリックするたびにs の配列を作成する必要があります。

const wizard = document.querySelector('#wizard');
wizard.addEventListener('click', ({ target }) => {
  // Make sure the clicked element is a <li>
  if (!target.matches('li')) return;
  
  const lis = [...wizard.children];
  const index = lis.indexOf(target);
  console.log(index);
});
<ul id="wizard">
    <li>Step 1</li>
    <li>Step 2</li>
</ul>


$(...)。indexOfは関数ではありません
カリーム

2
私の回答のコードスニペットのどれもそのエラーを生成しません-「コードスニペットの実行」を押して、それらが機能していることを確認できます。あなたはjQueryのを使用しているように聞こえるが、私の答えは、この種のものを達成する方法を示している-あなたがそのエラーを取得している場合は、別のコードを使用していることなく、 jQueryの
CertainPerformance

けっこうだ。はい、私はJQueryを使用しています。ありがとう
カリーム

3

DelegateとLiveは使いやすいですが、動的に追加されるli:sがなくなる場合は、通常のバインド/クリックでイベントの遅延を使用することもできます。DOMで新しい一致する要素を監視する必要がないため、この方法を使用するとパフォーマンスが向上するはずです。実際の数値はありませんが、理にかなっています:)

$("#wizard").click(function (e) {
    var source = $(e.target);
    if(source.is("li")){
        // alert index of li relative to ul parent
        alert(source.index());
    }
});

あなたはjsFiddleでそれをテストすることができます:http ://jsfiddle.net/jimmysv/4Sfdh/1/


1
この「DOMを監視する必要がない」と言ったとき、何を指しているのですか?jqデリゲートはdomを監視しません。
redsquare

@redsquare DelegateはLiveのより効率的なバリアントであるという印象を受けました。これはapi.jquery.com/delegateからのものです。「現在または将来、特定のルート要素のセットに基づいて、セレクターに一致するすべての要素の1つ以上のイベントにハンドラーをアタッチします。」将来的に拘束するために監視する必要がありますか?
jimmystormig

いいえ、上記のコードのようにコンテナで委任を使用するだけです。コンテナーに新しいli要素を挿入した場合でも、コンテナーのクリックイベントが発生し、すべてが機能します。監視は必要ありません。
redsquare

@redsquareはい、あなたは正しいです。私のソリューションは、DOMのロード後に新しい要素が追加されても機能します。Delegateは内部でLiveを使用しているため(stackoverflow.com/questions/2954932/…を参照)、依然として最適化されているように感じられますが、利便性は低くなります。しかし、言ったように、私には数がありません。
jimmystormig

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.