How to tell which row number is clicked in a table?

前端 未结 6 519
陌清茗
陌清茗 2020-12-01 03:28

I have a table like the following:

6条回答
  •  臣服心动
    2020-12-01 04:07

    A better approach would be to delegate the event, which means catching it as it bubbles to the parent node.

    delegation - overview

    This solution is both more robust and efficient.

    It allows the event to be handled even if more rows are dynamically added to the table later, and also results in attaching a single event handler to the parent node (table element), instead of one for each child node (tr element).

    Assuming that the OP's example is a simplified one, the table's structure can be more complex, for example:

    
        ...
        

    1

    2

    3

    Therefore, a simplistic approach such as getting e.target.parentElement will not work, as clicking the internal

    and clicking the center will produce different results.

    Using delegation normalizes the event handling, only assuming that there are no nested tables.

    implementation

    Both of the following snippets are equivalent:

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

    They attach a listener to table element and handle any event that bubbles from the table rows. The current API is the on method and the delegate method is legacy API (and actually calls on behind the scenes).

    Note that the order of parameters to both functions is different.

    example

    A comparison between direct handler attachment and delegation is available below or 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($('extraextraextra')[0])
    });
    tr:hover{
        background:#ffffd;
    }
    
    button.add-row {
        margin-bottom: 5px;
    }
    
    
    
    
    
    

    Event handling test

    Add rows to both tables and see the difference in handling.

    Event delegation attaches a single event listener and events related to newly added children are caught.

    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.

    Delegation

    row index: unknown

    normal normal normal

    nested

    nested

    nested

    normal normal

    nested

    Direct attachment

    row index: unknown

    normal normal normal

    nested

    nested

    nested

    normal normal

    nested

    Here's the demo on jsFiddle.

    P.S:

    If you do have nested tables (or, in the general case, wish to delegate to elements with specific depth), you can use this suggestion from the jQuery bug report.

提交回复
热议问题