Bootstrap table-将鼠标悬停在 rowspan 上以突出显示单元格所属的所有行

Bootstrap table-hover with rowspan to highlight all rows the cell belongs to

我试图在 Bootstrap table 上实现 table-hover class 的效果,它有多个 rowspan 值。这意味着我想突出显示同一行中的每个单元格。这是当前 table-hover 行为的片段:

.td-centered {
  vertical-align: middle!important;
  text-align: center;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<table class="table text-center text-nowrap table-bordered table-hover">
  <thead>
    <tr>
      <th scope="col" class="h5 font-weight-bold">
        Date
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Title
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Amount
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Price
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Value
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Category
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Mean
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <th scope="row" class="td-centered" rowspan="3">2020-06-25</th>
      <td class="td-centered" rowspan="2">Some name 1</td>
      <td class="td-centered">2</td>
      <td class="td-centered">30.00 PLN</td>
      <td class="td-centered">60.00 PLN</td>
      <td class="td-centered" rowspan="3">Own</td>
      <td class="td-centered">Cash</td>
    </tr>
    <tr>
      <td class="td-centered">1</td>
      <td class="td-centered" rowspan="2">20.00 PLN</td>
      <td class="td-centered">20.00 PLN</td>
      <td class="td-centered">Bank Account</td>
    </tr>
    <tr>
      <td class="td-centered">Some name 2</td>
      <td class="td-centered">2</td>
      <td class="td-centered">40.00 PLN</td>
      <td class="td-centered">PayPal</td>
    </tr>
  </tbody>
</table>

预期行为如下所示:

.td-centered {
  text-align: center;
  vertical-align: middle !important;
}

.red-bg {
  background-color: red;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<table class="table text-center text-nowrap table-bordered">
  <thead>
    <tr>
      <th scope="col" class="h5 font-weight-bold">
        Date
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Title
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Amount
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Price
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Value
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Category
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Mean
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td scope="row" class="td-centered red-bg" rowspan="3"><b>Hover here</b></td>
      <td class="td-centered red-bg" rowspan="2">Some name 1</td>
      <td class="td-centered red-bg">2</td>
      <td class="td-centered red-bg">2</td>
      <td class="td-centered red-bg">4</td>
      <td class="td-centered red-bg" rowspan="3">X</td>
      <td class="td-centered red-bg">Y</td>
    </tr>
    <tr>
      <td class="td-centered red-bg">1</td>
      <td class="td-centered red-bg" rowspan="2">1</td>
      <td class="td-centered red-bg">1</td>
      <td class="td-centered red-bg">Z</td>
    </tr>
    <tr>
      <td class="td-centered red-bg">Some name 2</td>
      <td class="td-centered red-bg">2</td>
      <td class="td-centered red-bg">2</td>
      <td class="td-centered red-bg">A</td>
    </tr>

    <tr>
      <td></td>
    </tr>

    <tr>
      <td scope="row" class="td-centered red-bg" rowspan="3">Some date</td>
      <td class="td-centered red-bg" rowspan="2"><b>Hover here</b></td>
      <td class="td-centered red-bg">2</td>
      <td class="td-centered red-bg">2</td>
      <td class="td-centered red-bg">4</td>
      <td class="td-centered red-bg" rowspan="3">X</td>
      <td class="td-centered red-bg">Y</td>
    </tr>
    <tr>
      <td class="td-centered red-bg">1</td>
      <td class="td-centered red-bg" rowspan="2">1</td>
      <td class="td-centered red-bg">1</td>
      <td class="td-centered red-bg">Z</td>
    </tr>
    <tr>
      <td class="td-centered">Some name 2</td>
      <td class="td-centered">2</td>
      <td class="td-centered">2</td>
      <td class="td-centered">A</td>
    </tr>

    <tr>
      <td></td>
    </tr>

    <tr>
      <td scope="row" class="td-centered red-bg" rowspan="3">Some date</td>
      <td class="td-centered red-bg" rowspan="2">Some name 1</td>
      <td class="td-centered red-bg"><b>Hover here</b></td>
      <td class="td-centered red-bg">2</td>
      <td class="td-centered red-bg">4</td>
      <td class="td-centered red-bg" rowspan="3">X</td>
      <td class="td-centered red-bg">Y</td>
    </tr>
    <tr>
      <td class="td-centered">1</td>
      <td class="td-centered" rowspan="2">1</td>
      <td class="td-centered">1</td>
      <td class="td-centered">Z</td>
    </tr>
    <tr>
      <td class="td-centered">Some name 2</td>
      <td class="td-centered">2</td>
      <td class="td-centered">2</td>
      <td class="td-centered">A</td>
    </tr>
  </tbody>
</table>

我可以使用 jQuery 来实现它。这个问题的最佳解决方案是 bootstrap-only,但我也可以使用普通的 CSS。如果你能帮助我,那就太棒了:)

我想到了这个解决方案:

jQuery(() => {
  if ($("#table-multi-hover").length) {
    const headerValues = Array.from($("thead")[0].children[0].children)
      .map(item => item.innerText.toLowerCase());

    let table = [];

    const tableCells = Array.from($("tbody")[0].children)
      .map(item => item.children)
      .map(item => Array.from(item));

    for (let i = 0; i < tableCells.length; i++) {
      let tempObj = {};
      for (let j = 0; j < tableCells[i].length; j++) {
        tempObj[tableCells[i][j].attributes.rep.value] = tableCells[i][j];
      }

      for (let j = 0; j < headerValues.length; j++) {
        if (i != 0 && tempObj[headerValues[j]] == undefined) {
          tempObj[headerValues[j]] = table[i - 1][headerValues[j]];
        }
      }
      table.push(Object.assign({}, tempObj));
    }

    $("tbody td, tbody th").on("mouseover", event => {
      const rowIndex = parseInt(event.currentTarget.parentElement.attributes.i.value);
      const rep = event.currentTarget.attributes.rep.value;
      const rowspan = event.currentTarget.attributes.rowspan != undefined ?
        parseInt(event.currentTarget.attributes.rowspan.value) : 1;

      for (let i = 0; i < rowspan; i++) {
        for (let j in table[rowIndex + i]) {
          $(table[rowIndex + i][j]).addClass("red-bg");
        }
      }
    });

    $("tbody td, tbody th").on('mouseleave', event => {
      const rowIndex = parseInt(event.currentTarget.parentElement.attributes.i.value);
      const rep = event.currentTarget.attributes.rep.value;
      const rowspan = event.currentTarget.attributes.rowspan != undefined ?
        parseInt(event.currentTarget.attributes.rowspan.value) : 1;

      for (let i = 0; i < rowspan; i++) {
        for (let j in table[rowIndex + i]) {
          $(table[rowIndex + i][j]).removeClass("red-bg");
        }
      }
    });
  }
});
td,
th {
  text-align: center;
  vertical-align: middle !important;
}

.red-bg {
  background-color: red;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table text-center text-nowrap table-bordered" id="table-multi-hover">
  <thead>
    <tr>
      <th scope="col" class="h5 font-weight-bold">
        Date
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Title
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Amount
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Price
      </th>
      <th scope="col" class="h5 font-weight-bold">
        Value
      </th>
    </tr>
  </thead>

  <tbody>
    <tr i="0">
      <th rowspan="3" scope="row" rep="date">2020-06-25</th>
      <td rowspan="2" rep="title">Some name 1</td>
      <td rep="amount">2</td>
      <td rep="price">30.00 PLN</td>
      <td rep="value">60.00 PLN</td>
    </tr>
    <tr i="1">
      <td rep="amount">1</td>
      <td rowspan="2" rep="price">20.00 PLN</td>
      <td rep="value">20.00 PLN</td>
    </tr>
    <tr i="2">
      <td rep="title">Some name 2</td>
      <td rep="amount">2</td>
      <td rep="value">40.00 PLN</td>
    </tr>
    <tr i="3">
      <th rowspan="3" scope="row" rep="date">2020-06-24</th>
      <td rowspan="2" rep="title">Some name 1</td>
      <td rep="amount">2</td>
      <td rep="price">30.00 PLN</td>
      <td rep="value">60.00 PLN</td>
    </tr>
    <tr i="4">
      <td rep="amount">1</td>
      <td rowspan="2" rep="price">20.00 PLN</td>
      <td rep="value">20.00 PLN</td>
    </tr>
    <tr i="5">
      <td rep="title">Some name 2</td>
      <td rep="amount">2</td>
      <td rep="value">40.00 PLN</td>
    </tr>
  </tbody>
</table>

基本上你需要做的是:

  1. id 属性添加到您的 table 并将其设置为 table-multi-hover
  2. i 属性添加到 tbody 内的 tr 并将其设置为从 0 开始的行索引。
  3. rep 属性添加到您的 tdth 中,其值对应于您在 table header 中的小写值。

考虑到我制定此解决方案是为了解决我的问题,这意味着我假设 table 中没有漏洞并且不会设置任何 colspan 属性。我还假设 table 会像代码片段中那样有一个 thead。添加到元素中的 class 称为 red-bg.