web-dev-qa-db-fra.com

Comment savoir quel numéro de ligne est cliqué dans une table?

J'ai une table comme celle-ci:

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

Lorsqu'un utilisateur clique sur la table, comment puis-je obtenir l'index de cette ligne (élément tr?)?

Par exemple, lorsque je clique sur le premier tr (avec 1s dans le tableau ci-dessus), il devrait le ramasser et renvoyer 1.

46
Muhammad Zeeshan

Cela vous donnerait l'index de la ligne cliquée, en commençant par un:

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

Si vous souhaitez renvoyer le numéro stocké dans cette première cellule de chaque ligne:

$('#thetable').find('tr').click( function(){
  var row = $(this).find('td:first').text();
  alert('You clicked ' + row);
});
74
Ken Redler

Une meilleure approche consisterait à déléguer l’événement, c’est-à-dire l’attraper au moment où il émet des bulles au nœud parent.

délégation - aperçu

Cette solution est à la fois plus robuste et efficace.

Il permet de gérer l’événement même si plusieurs lignes sont ajoutées dynamiquement à la table ultérieurement. Cela implique également de lier un seul gestionnaire d’événements au nœud parent (table élément), au lieu d’une pour chaque nœud enfant ( tr element).

En supposant que l'exemple du PO soit simplifié, la structure de la table peut être plus complexe, par exemple:

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

Par conséquent, une approche simpliste telle que l’obtention de e.target.parentElement Ne fonctionnera pas, car cliquer sur le bouton interne <p> Et cliquer sur le centre <td> Produira des résultats différents.

L'utilisation de la délégation normalise la gestion des événements, en supposant seulement qu'il n'y a pas de tables imbriquées.

la mise en oeuvre

Les deux extraits suivants sont équivalents:

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

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

Ils attachent un écouteur à l'élément table et gèrent tous les événements provoquant des bulles dans les lignes du tableau. L'API actuelle est la méthode on et la méthode delegate est une API héritée (et appelle en réalité on en coulisse).

Notez que l'ordre des paramètres des deux fonctions est différent.

exemple

Une comparaison entre l'attachement direct du gestionnaire et la délégation est disponible ci-dessous ou sur 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>

Voici le démo sur jsFiddle .

P.S:

Si vous avez des tables imbriquées (ou, dans le cas général, souhaitez déléguer des éléments d'une profondeur spécifique), vous pouvez utiliser cette suggestion du rapport de bogue jQuery .

23
MasterAM

Vous pouvez utiliser object.rowIndex propriété qui a un index commençant à 0.

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

Voir une démonstration de travail

17
rahul

Une solution simple et sans jQuery:

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

Bonus: Cela fonctionne même si les lignes sont ajoutées/supprimées dynamiquement

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

Pour la première tr, il alerte 0. Si vous souhaitez alerter 1, vous pouvez ajouter 1 à l'index.

3
miqbal

Dans certains cas, nous pourrions avoir deux tables, puis nous devions détecter les clics uniquement pour une table en particulier. Ma solution est la suivante:

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

DÉMO

2
Ludus H