Как навести курсор на , содержащий определенные данные

Мне нужно отобразить красный цвет фона в <td>, на который я навожу курсор. Например, если я навожу на «Яблоко», то «Яблоко» во всех <td> также будет окрашен в тот же цвет. В настоящее время при наведении на один <td> Apple</td> закрашивается только одна ячейка.

table {
margin: 2rem;
}

th, td {
border: 1px solid #333;
}

td:hover{
background-color:red
}

html {
font-size: 24px;
}
<h3>Table 1</h3>

<table>
<tr>
<th>Header 1.1</th>
<th>Header 1.2</th>
<th>Header 1.3</th>
</tr>
<tr>
<td>Apple</td>
<td>Orange</td>
<td>Lemon</td>
</tr>
<tr>
<td>Orange</td>
<td>Lemon</td>
<td>Apple</td>
</tr>
</table>

Свободный перевод вопроса How to hover that contain specific data от участника @Muneeb K.


Ответы (3 шт):

Автор решения: Alexandr_TT

Это невозможно сделать с помощью только HTML и CSS, поскольку CSS не знает о содержимом.

Используя Javascript, вы можете установить переменные CSS, которые, в свою очередь, будут устанавливать фон ячейки.

Этот фрагмент просматривает каждый элемент td и устанавливает стиль background: var(--name of fruit), поэтому, например, все ячейки яблока имеют стиль = background: var (- apple);. Затем, когда на td наводят курсор, JS устанавливает --apple в красный цвет, а когда курсор перемещается, он устанавливает его прозрачным.

Таким образом будут выделены все эти td's с background: var (- apple).

Нет необходимости перебирать все ячейки в таблице каждый раз, когда происходит наведение, вы можете сделать это, настроив все один раз в начале.

function setHighlight(e) {
  table.style.setProperty('--' + e.target.textContent, 'red');
}

function removeHighlight(e) {
  table.style.setProperty('--' + e.target.textContent, 'transparent');
}
const table = document.querySelector('table');
const tds = document.querySelectorAll('td');
tds.forEach(td => {
  td.addEventListener('mouseover', setHighlight);
  td.style.backgroundColor = 'var(--' + td.textContent + ')';
});
tds.forEach(td => {
  td.addEventListener('mouseout', removeHighlight);
});
<h3>Table 1</h3>

<table>
  <tr>
    <th>Header 1.1</th>
    <th>Header 1.2</th>
    <th>Header 1.3</th>
  </tr>
  <tr>
    <td>Apple</td>
    <td>Orange</td>
    <td>Lemon</td>
  </tr>
  <tr>
    <td>Orange</td>
    <td>Lemon</td>
    <td>Apple</td>
  </tr>
</table>

Свободный перевод ответа от участника @A Haworth.

→ Ссылка
Автор решения: Alexandr_TT

Вы можете сделать это с помощью jQuery. Попробуйте запустить следующий фрагмент.

$('.apple').hover(
  function(){
        $('.apple').css({"background":"red"});
  },function(){
        $('.apple').css({"background":"white"});
  })
  
$('.orange').hover(
  function(){
        $('.orange').css({"background":"orange"});
  }
  ,function(){
        $('.orange').css({"background":"white"});
  }
)

$('.lemon').hover(
  function(){
        $('.lemon').css({"background":"yellow"});
  }, function(){
        $('.lemon').css({"background":"white"});
})
html {
  font-size: 24px;
}

table {
  margin: 2rem;
}

th, td {
  border: 1px solid #333;
}

td span {
  display: block;
}

td:hover span.apple {
  background-color:red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>Table 1</h3>

<table>
  <tr>
    <th>Header 1.1</th>
    <th>Header 1.2</th>
    <th>Header 1.3</th>
  </tr>
  <tr>
    <td><span class="apple">Apple</span></td>
    <td><span class="orange">Orange</span></td>
    <td><span class="lemon">Lemon</span></td>
  </tr>
  <tr>
    <td><span class="orange">Orange</span></td>
    <td><span class="lemon">Lemon</span></td>
    <td><span class="apple">Apple</span></td>
  </tr>
</table>

Свободный перевод ответа от участника @Viira.

→ Ссылка
Автор решения: UModeL

Используя в jQuery селектор по тексту, можно чуть сократить код и сделать его более универсальным:

const $TD = $('td');
$($TD).hover(
  function() {
    let $text = $(this).text();
    $($TD).filter(`:contains('${$text}')`).css({'background': $text})
  },
  function() {
    $($TD).css({'background': ''})
  }
)
html { font-size: 24px; } table { margin: auto; } th, td { border: 1px solid #333; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr><th>Header 1.1</th><th>Header 1.2</th><th>Header 1.3</th><th>Header 1.4</th><th>Header 1.5</th><th>Header 1.5</th></tr>
  <tr><td>Tomato</td><td>Orange</td><td>Lime</td><td>Olive</td><td>Plum</td><td>Chocolate</td></tr>
  <tr><td>Orange</td><td>Plum</td><td>Tomato</td><td>Lime</td><td>Chocolate</td><td>Olive</td></tr>
  <tr><td>Lime</td><td>Chocolate</td><td>Olive</td><td>Orange</td><td>Plum</td><td>Tomato</td></tr>
</table>

Если текст не совпадает с названиями цветов в HTML, то можно сделать "ассоциативный массив" и там подставить необходимые значения:

const $MENU = {
  'Помидор' : 'Tomato',
  'Апельсин': '50% 50% / 30% 100% radial-gradient(circle closest-side at center, orange 70%, transparent 71%)',
  'Лайм'    : 'repeating-linear-gradient(45deg, lime 0% 5%, transparent 6% 10%)',
  'Оливки'  : 'Olive',
  'Слива'   : 'right center / contain url(https://img.icons8.com/color/2x/plum.png) no-repeat',
  'Шоколад' : '#d2691e'
};
const $TD = $('td');
$($TD).hover(
  function() {
    let $text = $(this).text();
    $($TD).filter(`:contains('${$text}')`).css({'background': $MENU[$text]})
  },
  function() {
    $($TD).css({'background': ''})
  }
)
html { font-size: 24px; } table { margin: auto; } th, td { border: 1px solid #333; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr><th>Header 1.1</th><th>Header 1.2</th><th>Header 1.3</th><th>Header 1.4</th><th>Header 1.5</th><th>Header 1.5</th></tr>
  <tr><td>Помидор</td><td>Апельсин</td><td>Лайм</td><td>Оливки</td><td>Слива</td><td>Шоколад</td></tr>
  <tr><td>Апельсин</td><td>Слива</td><td>Помидор</td><td>Лайм</td><td>Шоколад</td><td>Оливки</td></tr>
  <tr><td>Лайм</td><td>Шоколад</td><td>Оливки</td><td>Апельсин</td><td>Слива</td><td>Помидор</td></tr>
</table>

Расширяя далее такой подход, можно изменять уже не отдельные свойства, а переключать сразу CSS-классы.

→ Ссылка