简体   繁体   中英

Table column to change color upon hover

I have been piecing together a table format by using a range of templates that I have found online (am not a skilled programmer myself). I am trying to create a table that will highlight both the entire row and column when you hover over a specific table cell while it also includes a scrolling feature with the top row fixed. I have figured out how to highlight the row but am having difficulties with the column.

I have created a JSFiddle, which should reveal the problem: https://jsfiddle.net/n2p0zj6m/4/

I am using the code below to add the relevant classes to the table upon hover of a table cell. I am very sure that the error lies in this code somewhere but I can't figure out why this doesn't work.

  (function ($) {
    "use strict";
    $('.column100').on('mouseover',function(){
        var table1 = $(this).parent().parent().parent();
        var table2 = $(this).parent().parent();
        var verTable = $(table1).data('vertable')+"";
        var column = $(this).data('column') + "";

        $(table2).find("."+column).addClass('hov-column-'+ verTable);
        $(table1).find(".row100.head ."+column).addClass('hov-column-head-'+ verTable);
    });

    $('.column100').on('mouseout',function(){
        var table1 = $(this).parent().parent().parent();
        var table2 = $(this).parent().parent();
        var verTable = $(table1).data('vertable')+"";
        var column = $(this).data('column') + "";

        $(table2).find("."+column).removeClass('hov-column-'+ verTable);
        $(table1).find(".row100.head ."+column).removeClass('hov-column-head-'+ verTable);
    });
  })(jQuery);

I will also include a snippet of the HTML structure below:

  <div class="tbl-header">
    <table data-vertable="ver1" cellpadding="0" cellspacing="0" border="0">
      <thead>
        <tr class="row100 head">
          <th class="column100 column1" data-column="column1">Code</th>
          <th class="column100 column2" data-column="column2">Company</th>
          <th class="column100 column3" data-column="column3">Price</th>
          <th class="column100 column4" data-column="column4">Change</th>
          <th class="column100 column5" data-column="column5">Change %</th>
        </tr>
      </thead>
    </table>
  </div>
  <div class="tbl-content">
    <table data-vertable="ver1" cellpadding="0" cellspacing="0" border="0">
      <tbody>
        <tr class="row100">
          <td class="column100 column1" data-column="column1">AAC</td>
          <td class="column100 column2" data-column="column2">AUSTRALIAN COMPANY </td>
          <td class="column100 column3" data-column="column3">$1.38</td>
          <td class="column100 column4" data-column="column4">+2.01</td>
          <td class="column100 column5" data-column="column5">-0.36%</td>
        </tr>

One thing, is there's no need to separate the various levels of the table into different divs - this creates issues, and will confuse any robots/accessibility technology. In my snippet below, I've merged it into a single table. Using thead and tbody instead.

Also, with the approach I use (collecting the index of the cell - thus its column) there's no need for extra data-x or classes for tracking. And if your goal is for styling purposes, you should look into :nth-child() to create alternating rows and the like.

 $('tbody td').on('mouseover', function() { // Triggers when a table cell is hovered under a tbody column = $(this).index(); // Find which column the cell belongs to (its index amongst its siblings) $(this).parent().siblings().each(function() { // loop over all rows except current (the siblings) $(this).children().eq(column).addClass('colHover'); // addClass to the cell in the same column }); }); $('tbody td').on('mouseout', function() { // Triggers when leaving a table cell $(this).parent().siblings().each(function() { $(this).children().removeClass('colHover'); // removeClass from all children, of all siblings }); }); 
 table thead tr { background-color: #AAA; } table td, table th { padding: .5em .75em; } table tr td:nth-child(n+2) { text-align: center; } table tbody tr:hover, table tbody tr td.colHover { background-color: #FFDDFF; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="tblFinance"> <table data-vertable="ver1" cellpadding="0" cellspacing="0" border="0"> <thead> <tr> <th>Code</th> <th>Company</th> <th>Price</th> <th>Change</th> <th>Change %</th> </tr> </thead> <tbody> <tr class="row100"> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr class="row101"> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr class="row102"> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr class="row103"> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> </tbody> </table> </div> 

EDIT : I've built an extra function, which attaches an event to scrolling. Once the user has scrolled to (or past) the top of the table, the <tr> inside the <thead> becomes "sticky" - it applies position: fixed , and adjusts the table to handle the missing row without bouncing the page around.

NOTE : This is NOT very scalable, in its current form. It will only really support a single "sticky" element, in the specific table.

 $(document).ready(() => { var tblObject = $('table#tblFinance'); var tblTop = tblObject.offset().top; // Find Table's offset from the top of the page var tblSticky = false; // reduce redundant conditional spam $(window).scroll(() => { if (!tblSticky && $(document).scrollTop() >= tblTop) { // If Sticky is OFF, and user scrolls to/below the table's top tblObject.find('thead tr').css('position', 'fixed'); // Set Position: fixed tblObject.css('padding-top', tblObject.find('thead tr').outerHeight() + 'px'); // Add padding to table, to account for <tr> being removed from the flow tblSticky = true; // Enable Sticky } else if (tblSticky && $(document).scrollTop() <= tblTop) { // If Sticky is ON, and user scrolls to/above the table's top tblObject.find('thead tr').css('position', 'static'); // Set Position: Static tblObject.css('padding-top', '0'); // Remove padding; <tr> is back in the flow tblSticky = false; //Disable Sticky } }); }); $('tbody td').on('mouseover', function() { // Triggers when a table cell is hovered under a tbody column = $(this).index(); // Find which column the cell belongs to (its index amongst its siblings) $(this).parent().siblings().each(function() { // loop over all rows except current (the siblings) $(this).children().eq(column).addClass('colHover'); // addClass to the cell in the same column }); }); $('tbody td').on('mouseout', function() { // Triggers when leaving a table cell $(this).parent().siblings().each(function() { $(this).children().removeClass('colHover'); // removeClass from all children, of all siblings }); }); 
 table { text-align: center; } table thead tr { top: 0; background-color: #AAA; } table td, table th { padding: .5em .75em; } table td:first-child, table th:first-child { width: 80px; } table td:nth-child(2), table th:nth-child(2) { width: 300px; } table td:nth-child(n+3), table th:nth-child(n+3) { width: 100px; } table tbody tr:hover, table tbody tr td.colHover { background-color: #FFDDFF; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div> <h1>Title</h1> <p>Some content, to push the table down a bit.</p> <table id="tblFinance" data-vertable="ver1" cellpadding="0" cellspacing="0" border="0"> <thead> <tr> <th>Code</th> <th>Company</th> <th>Price</th> <th>Change</th> <th>Change %</th> </tr> </thead> <tbody> <tr> <td>AAA</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>BBB</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>CCC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>DDD</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> <tr> <td>AAC</td> <td>AUSTRALIAN COMPANY </td> <td>$1.38</td> <td>+2.01</td> <td>-0.36%</td> </tr> </tbody> </table> </div> 

If I understood correctly, I think your problem is in the CSS. Your columns are getting the right class hov-column-ver1 , but in the CSS you are only giving the green background to the elements under tbl-header :

.tbl-header .hov-column-ver1 {
  background-color: green;
}

You need to add the style for the elements under tbl-content . Add this in your CSS block:

.tbl-content .hov-column-ver1 {
  background-color: green;
}

Is this what you meant?

PS Please consider to review the closest() element in jQuery. Instead of using .parent().parent().parent() you could use .closest("table") . IMHO it is really useful in case the HTML structure changes as it will not affect your JS code. It is also more friendly to read :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM