it-swarm-ru.tech

Получить индекс элемента как дочерний относительно родителя

Допустим, у меня есть эта разметка:

<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".

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

Однако вместо того, чтобы прикреплять обработчик одного клика для каждого элемента списка, лучше (с точки зрения производительности) использовать delegate , который будет выглядеть следующим образом:

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

В jQuery 1.7+ вы должны использовать on . Приведенный ниже пример связывает событие с элементом #wizard, работающим как событие делегата:

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

что-то вроде:

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

Взгляните на это пример .

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

Еще один способ

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

Демо https://jsfiddle.net/m9xge3f5/

3
h0mayun

Delegate и Live просты в использовании, но если у вас больше не будет динамически добавляться li: s, вы также можете использовать отладку событий с обычным bind/click. При использовании этого метода должно быть некоторое повышение производительности, так как 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/

3
jimmystormig

Нет необходимости требовать большую библиотеку, такую ​​как jQuery, если вы этого не хотите. Чтобы достичь этого с помощью встроенной манипуляции с DOM, получите коллекцию братьев и сестер li в массиве и, нажав, проверьте элемент indexOf clicked в этом массиве.

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>

Или, если дочерние элементы могут изменяться динамически (как со списком задач), вам придется создавать массив lis при каждом щелчке, а не заранее:

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>
0
CertainPerformance