Add jQuery hover effect across two tables

2019-04-13 16:58发布

问题:

I have two HTML tables in divs floated next to each other. The second div is scrollable in the horizontal direction, so in effect it looks like one big table where the first few columns are 'frozen' and the others can be scrolled.

The following jQuery works great to highlight a row in one table when the user hovers over it:

$("table.grid tr:not(:first-child)")
  .hover(
    function () { $(this).addClass("highlight"); },
    function () { $(this).removeClass("highlight"); }
  );

Note that the :not(:first-child) prevents the header being highlighted.

How can I amend this so that it also highlights the corresponding row in the other table (which also has a class of grid)?

In other words, if I hover over the nth row in either table, then the nth rows in both tables are highlighted.

EDIT: The HTML looks like:

<div>
  <div style="float: left">
    <table id="names" class="grid">
      <tr><th>Last</th><th>First</th></tr>
      <tr><td>Smith</td><td>John</td></tr>
      <!-- etc -->
      </table>
  </div>
  <div style="float: left; overflow-x: scroll">
    <table id="results" class="grid">
      <tr><th>Test 1</th><th>Test 2</th></tr>
      <tr><td>50%</td><td>70%</td></tr>
      <!-- etc -->
    </table>
  </div>
  <div style="clear: both">
  </div>
</div>

回答1:

The trick is to grab all the <tr>s at the beginning and then combine $(this).index(), filter, and :nth-child to select the right rows in both tables at once:

var $trs = $('table.grid tr:not(:first-child)');
$trs.hover(
    function() {
        var i = $(this).index() + 1;
        $trs.filter(':nth-child(' + i + ')').addClass('highlight');
    },
    function() {
        var i = $(this).index() + 1;
        $trs.filter(':nth-child(' + i + ')').removeClass('highlight');
    }
);

Demo: http://jsfiddle.net/ambiguous/54thG/

The index call gives you the position of the <tr> being hovered with respect to its siblings in $trs, then you adjust by 1 because index is zero-based but :nth-child (being a CSS selector) is one-based, and fiddle with the class on both rows at once.



回答2:

Here is what I figured out:

HTML:

<html>
    <style>
    .highlight {background:gray;}
    </style>
    <body>
        <div>
            <div style="float: left">
                <table id="names" class="grid" style="width:200px">
                    <tr class="row0"><th style="width:40%">Last</th><th>First</th></tr>
                    <tr class="row1"><td>Smith</td><td>John</td></tr>
                    <tr class="row2"><td>Smith</td><td>John</td></tr>
                    <tr class="row3"><td>Smith</td><td>John</td></tr>
                    <tr class="row4"><td>Smith</td><td>John</td></tr>
                    <!-- etc -->
                </table>
            </div>
            <div style="float: left; overflow-x: scroll">
                <table id="results" class="grid" style="width:200px">
                    <tr class="row0"><th>Test 1</th><th>Test 2</th></tr>
                    <tr class="row1"><td>50%</td><td>70%</td></tr>
                    <tr class="row2"><td>50%</td><td>70%</td></tr>
                    <tr class="row3"><td>50%</td><td>70%</td></tr>
                    <!-- etc -->
                </table>
            </div>
            <div style="clear: both"></div>
        </div>
    </body>
</html>

JS:

$(document).ready(function() {
    $("table#names tr:not(:first-child)").each(function(k, v){
        var self = this;
        // index: 0 = second row; 1= 3rd row... of table#names 
        // index+1 for other table's row: .find('tr.row'+(index+1))
        (function(index){ 
            $(self).hover(
                function() {
                    $(this).addClass("highlight");                

                    // go up to parent div of #names, then its siblings, then the siblings' table's row
                    // you could also just $('table#results')
                    $('table#names').parent().siblings().find('tr.row'+(index+1)).addClass("highlight");
                }, function() {
  $('table#names').parent().siblings().find('tr.row'+(index+1)).removeClass("highlight");
                    $(this).removeClass("highlight");
                }
            );
        })(k); // pass index so function above remembers it
    });
});

JSFiddle: http://jsfiddle.net/6aNy2/