Таблица начальной загрузки -наведите указатель мыши на rowspan, чтобы выделить все строки, к которым принадлежит ячейка

#html #css #bootstrap-4 #hover

#HTML #css #bootstrap-4 #наведите

Вопрос:

Я пытаюсь добиться эффекта table-hover класса в таблице начальной загрузки, которая имеет несколько 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, чтобы добиться этого. Предпочтительным решением этого вопроса было бы только для начальной загрузки, но я могу использовать и обычный CSS. Если бы вы могли мне помочь, это было бы потрясающе 🙂

Ответ №1:

Я придумал это решение:

 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 amp;amp; 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-multi-hover .
  2. Добавьте i атрибут к вашей tr внутренней tbody части и установите для него индексы ваших строк, начинающиеся с 0.
  3. Добавьте rep атрибут к вашему td и th со значениями, соответствующими вашим значениям в заголовке таблицы в нижнем регистре.

Примите во внимание, что я создал это решение в соответствии со своей проблемой, это означает, что я предполагаю, что в таблице не будет дыр и не будет никаких colspan атрибутов. Также я предполагаю, что таблица будет иметь thead то же, что и во фрагменте кода. Вызывается класс, который добавляется к элементам red-bg .