如何判断在表中单击了哪个行号?

时间:2010-12-24 06:40:31

标签: javascript jquery html html-table dom-events

我有一张如下表格:

<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 个答案:

答案 0 :(得分:73)

这将获得所点击行的索引,从一个开始:

$('#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);
});

答案 1 :(得分:23)

更好的方法是委托事件,这意味着在事件发生时将其捕获到父节点。

委托 - 概述

此解决方案更加强大和高效。

它允许处理事件,即使稍后将更多行动态添加到表中,并且还导致将单个事件处理程序附加到父节点(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>

这是demo on jsFiddle

P.S:

如果你有嵌套表(或者,在一般情况下,希望委托给具有特定深度的元素),你可以使用this suggestion from the jQuery bug report

答案 2 :(得分:17)

您可以使用索引从0开始的object.rowIndex属性。

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

查看working demo

答案 3 :(得分:6)

一个简单且无jQuery的解决方案:

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

加分:即使动态添加/删除行也能正常运行

答案 4 :(得分:3)

$('tr').click(function(){
 alert( $('tr').index(this) );
});

对于第一个tr,它会提醒0.如果要提醒1,可以将1添加到索引。

答案 5 :(得分:2)

在某些情况下,我们可能会有几个表,然后我们需要检测特定表的点击。我的解决方案是:

 #include Foo.h
 IFoo* IFoo::Create()
 {
     IFoo* f = new Foo(); // CRASH if ctor is NOT inline.
     f->DoSomething(); //CRASH
     return f;
 }

<强> DEMO