Как определить, какой номер строки выбран в таблице? - PullRequest
45 голосов
/ 24 декабря 2010

У меня есть таблица, подобная следующей:

<table>
   <tr>
      <td>1</td><td>1</td><td>1</td>
   </tr>
   <tr>
      <td>2</td><td>2</td><td>2</td>
   </tr>
   <tr>
      <td>3</td><td>3</td><td>3</td>
   </tr>
</table>

Когда пользователь нажимает на таблицу, как я могу получить индекс этой строки (tr элемент)?

Например, когда я нажимаю на первый tr1 s в приведенной выше таблице), он должен взять его и вернуть 1.

Ответы [ 6 ]

73 голосов
/ 24 декабря 2010

Это даст вам индекс строки, по которой щелкнули, начиная с единицы:

$('#thetable').find('tr').click( function(){
alert('You clicked row '+ ($(this).index()+1) );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="thetable">
   <tr>
      <td>1</td><td>1</td><td>1</td>
   </tr>
   <tr>
      <td>2</td><td>2</td><td>2</td>
   </tr>
   <tr>
      <td>3</td><td>3</td><td>3</td>
   </tr>
</table>

Если вы хотите вернуть число, сохраненное в первой ячейке каждой строки:

$('#thetable').find('tr').click( function(){
  var row = $(this).find('td:first').text();
  alert('You clicked ' + row);
});
23 голосов
/ 05 августа 2013

Лучшим подходом было бы делегировать событие, что означает его перехват по мере его появления на родительском узле.

делегирование - обзор

Это решение более надежное и эффективное.

Это позволяет обрабатывать событие, даже если позднее в таблицу динамически добавляется больше строк, а также приводит к присоединению одного обработчика события к родительскому узлу (элемент table) вместо одного для каждого дочернего узла ( tr элемент).

Если предположить, что пример OP является упрощенным, структура таблицы может быть более сложной, например:

<table id="indexedTable">
    ...
    <tr>
        <td><p>1</p></td>
        <td>2</td>
        <td><p>3</p></td>
    </tr>
</table>

Следовательно, упрощенный подход, такой как получение e.target.parentElement, не будет работать, так как щелчок по внутреннему <p> и нажатие по центру <td> приведут к другим результатам.

Использование делегирования нормализует обработку событий, только при условии, что нет вложенных таблиц.

осуществление

Оба следующих фрагмента эквивалентны:

$("#indexedTable").delegate("tr", "click", function(e) {
    console.log($(e.currentTarget).index() + 1);
});

$("#indexedTable").on("click", "tr", function(e) {
    console.log($(e.currentTarget).index() + 1);
});

Они прикрепляют слушателя к элементу table и обрабатывают любое событие, всплывающее из строк таблицы. Текущий API является методом on, а метод delegate является устаревшим API (и фактически вызывает on за кулисами).

Обратите внимание, что порядок параметров для обеих функций различен.

пример

Сравнение между прямым обработчиком и делегированием доступно ниже или на jsFiddle:

$("#table-delegate").on("click", "tr", function(e) {
  var idx = $(e.currentTarget).index() + 1;
  $("#delegation-idx").text(idx);  
  console.log('delegated', idx);
});

$("#table-direct tr").on("click", function(e) {
  var idx = $(e.currentTarget).index() + 1;
  $("#direct-idx").text(idx);
  console.log('direct', idx);
});

$('[data-action=add-row]').click(function(e) {
  var id = e.target.dataset.table;
  $('#' + id + ' tbody')
    .append($('<tr><td>extra</td><td>extra</td><td>extra</td></tr>')[0])
});
tr:hover{
    background:#ddd;
}

button.add-row {
    margin-bottom: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>


<h1>Event handling test</h1>
<p>Add rows to both tables and see the difference in handling.</p>
<p>Event delegation attaches a single event listener and events related to newly added children are caught.</p>
<p>Direct event handling attaches an event handler to each child, where children added after the inital handler attachment don't have a handler attached to them, and therefore their indices won't be logged to console.</p>
<h2>Delegation</h2>
<p><span>row index: </span><span id="delegation-idx">unknown</span></p>
<button class="add-row" data-action="add-row" data-table="table-delegate">Add row to delegation</button>
<table id="table-delegate" class="table">
    <tbody>
    <tr>
        <td>normal</td>
        <td>normal</td>
        <td>normal</td>
    </tr>
    <tr>
        <td><p>nested</p></td>
        <td><p>nested</p></td>
        <td><p>nested</p></td>
    </tr>
    <tr>
        <td>normal</td>
        <td>normal</td>
        <td><p>nested</p></td>
    </tr>

</table>

<h2>Direct attachment</h2>
<p><span>row index: </span><span id="direct-idx">unknown</span></p>
<button class="add-row" data-action="add-row" data-table="table-direct">Add row to direct</button>
<table id="table-direct" class="table">
<tbody>
    <tr>
        <td>normal</td>
        <td>normal</td>
        <td>normal</td>
    </tr>
    <tr>
        <td><p>nested</p></td>
        <td><p>nested</p></td>
        <td><p>nested</p></td>
    </tr>
    <tr>
        <td>normal</td>
        <td>normal</td>
        <td><p>nested</p></td>
    </tr>
    
</tbody>
</table>

Вот демоверсия для jsFiddle .

P.S:

Если у вас есть вложенные таблицы (или, в общем случае, вы хотите делегировать элементы с определенной глубиной), вы можете использовать это предложение из отчета об ошибке jQuery .

17 голосов
/ 24 декабря 2010

Вы можете использовать свойство object.rowIndex, индекс которого начинается с 0.

$("table tr").click(function(){
    alert (this.rowIndex);
});

См. рабочая демонстрация

6 голосов
/ 26 ноября 2016

Простое и бесплатное решение jQuery:

document.querySelector('#elitable').onclick = function(ev) {
   // ev.target <== td element
   // ev.target.parentElement <== tr
   var index = ev.target.parentElement.rowIndex;
}

Бонус: Работает, даже если строки добавляются / удаляются динамически

3 голосов
/ 24 декабря 2010
$('tr').click(function(){
 alert( $('tr').index(this) );
});

Для первых tr, он предупреждает 0. Если вы хотите предупредить 1, вы можете добавить 1 к индексу.

2 голосов
/ 19 мая 2016

В некоторых случаях у нас может быть пара таблиц, а затем нам нужно обнаружить щелчок только для конкретной таблицы.Мое решение таково:

<table id="elitable" border="1" cellspacing="0" width="100%">
  <tr>
 <td>100</td><td>AAA</td><td>aaa</td>
  </tr>
  <tr>
<td>200</td><td>BBB</td><td>bbb</td>
   </tr>
   <tr>
<td>300</td><td>CCC</td><td>ccc</td>
  </tr>
</table>


    <script>
    $(function(){
        $("#elitable tr").click(function(){
        alert (this.rowIndex);
        });
    });
    </script>

DEMO

...