Как выбрать случай таблицы, нажав на нее, не используя идентификатор или класс? - PullRequest
0 голосов
/ 13 февраля 2020

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

Вот функция, которая должна делать это в javascript:

let color = "red";
function changementColor(cell) {
     document.createElement('style').innerHTML = cell + " { background-color: " + color + "; }"
}

А вот где функция вызывается в HTML:

<td class='table' onClick='changementColor(this)'></td>

Создан стиль

"[object HTMLTableCellElement] { background-color: red; }"

Ответы [ 3 ]

0 голосов
/ 13 февраля 2020

Конечно, это можно изменить, но я думаю, это то, чего вы хотите достичь.

let rows = document.querySelector("table").rows

Array.from(rows).forEach(function(row){
  let cells = row.cells;
  Array.from(cells).forEach(function(cell){
    cell.addEventListener('click', function(e){
      let el = e.target;
      el.style.backgroundColor = 'red';
    });
  });
});
table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}
<table>
  <tr>
    <th>Company</th>
    <th>Contact</th>
    <th>Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Centro comercial Moctezuma</td>
    <td>Francisco Chang</td>
    <td>Mexico</td>
  </tr>
  <tr>
    <td>Ernst Handel</td>
    <td>Roland Mendel</td>
    <td>Austria</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>Helen Bennett</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Laughing Bacchus Winecellars</td>
    <td>Yoshi Tannamuri</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Giovanni Rovelli</td>
    <td>Italy</td>
  </tr>
</table>
0 голосов
/ 13 февраля 2020

Существует два основных метода (без использования jQuery) добавления прослушивателя событий ко многим элементам. Первый довольно похож на ответ @marmeladze; Другой метод заключается в том, чтобы прикрепить прослушиватель событий к чему-то выше дерева DOM (например, к таблице вместо td) и использовать всплывающее сообщение

Attach обработчик событий для каждой ячейки таблицы

Сначала использовался метод, подобный Мармеладзе ...
, но (1) я параноидален в отношении создания нескольких копий одной и той же функции, по одной для каждой ячейки таблицы, и (2) итерация может быть упрощена путем выбора ячеек <td> вместо итерации строк.

Чтобы гарантировать, что есть только одна копия функции, я объявляю ее как константную прямо в начале.

const redFunc = function(e) { let el = e.target; el.style.backgroundColor = 'red'; };

Теперь я выбираю все ячейки таблицы - я слегка изменил таблицу примеров, присвоив ей правильные <thead> и <tbody> и id для более легкого выбора.

<table id="contacts">
  <thead>
    <tr>
      <th>Company</th>
      <th>Contact</th>
      <th>Country</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Alfreds Futterkiste</td>
      <td>Maria Anders</td>
      <td>Germany</td>
    </tr>
  etc.
  </tbody>

Выберите сразу все ячейки таблицы:
let cells = document.querySelectorAll('#contacts tbody td');

Теперь прикрепите обработчик щелчка ко всем ячейкам:
cells.forEach(c => c.addEventListener('click', redFunc));

Эти два шага могут быть объединенным, поэтому переменная cells не имеет Будет создано:

document.querySelectorAll('#contacts tbody td')
        .forEach(c => addEventListener('click', redFunc));

Все вместе:

const redFunc = function(e) {
  let el = e.target;
  el.style.backgroundColor = 'red';
};
const activeFunc = function(e) {
  e.target.classList.toggle('active');
};
//document.querySelectorAll('#contacts tbody td')
//        .forEach(c => addEventListener('click', redFunc));
document.querySelectorAll('#contacts tbody td')
        .forEach(c => addEventListener('click', activeFunc));
table {
  font-family: sans-serif;
  border-collapse: collapse;
  border: 1px solid black;
}
table tbody {
  border-top: 1px solid black;
}
table tbody td {
  border: 1px solid black;
}
table th, table td {
  padding: 5px;
}

table td.active {
  background-color: red;
}
<table id="contacts">
<thead>
  <tr>
    <th>Company</th>
    <th>Contact</th>
    <th>Country</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Centro comercial Moctezuma</td>
    <td>Francisco Chang</td>
    <td>Mexico</td>
  </tr>
  <tr>
    <td>Ernst Handel</td>
    <td>Roland Mendel</td>
    <td>Austria</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>Helen Bennett</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Laughing Bacchus Winecellars</td>
    <td>Yoshi Tannamuri</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Giovanni Rovelli</td>
    <td>Italy</td>
  </tr>
</tbody>
</table>

В реальной жизни я бы не стал напрямую манипулировать el.style.backgroundColor (как прокомментировал вопрос Владимир Серых); Я бы переключил класс в ячейке, по которой щелкнули - щелчок добавляет класс, щелчок снова удаляет класс
el.classList.toggle('active')
с правилом CSS, например table td.active { background-color: red; }
(на самом деле, я ушел назад и сделал это изменение в стеке-фрагменте)

(совет: имена классов должны описывать , что что-то есть, или состояние , что-то в, так что щелчок делает ячейка «активна», она не делает ее «красной», тогда вы решаете, что активные ячейки должны отображаться красным, используя правило CSS)

… или, если вы хотите, чтобы за раз выделялась только одна ячейка… щелчок удаляет класс из всех ячеек, а затем добавляет его в ячейку, на которую щелкнули.

Присоедините обработчик событий к таблице

Сначала обрабатывается событие по самой конкретной c вещи, которая была нажата: ячейка таблицы td в данном случае; затем событие всплывает, до tr, tbody и, в конечном итоге, table

. Мы можем прикрепить обработчик события к таблице , но затем обработать его, только если оно был td , который был фактически нажат.
Когда вы получаете событие, вы можете получить элемент, и тип этого элемента - event.target.nodeName
Если это === 'TD', тогда мы щелкнул элемент td, поэтому переключаем класс целевого узла события.

document.querySelector('table#contacts').addEventListener('click', e => {
  let el = e.target;
  if (el.tagName === 'TD') {
    el.classList.toggle('active');
  }
});

При этом подключается только один обработчик событий, а не один для каждого элемента td, поэтому у меня нет беспокоиться о нескольких копиях моей функции обработки событий.


(супер-эксперты: оправдана ли моя паранойя? или каким-то образом анонимные функции объединяются в одну копию?)

0 голосов
/ 13 февраля 2020

Заменить

document.createElement('style').innerHTML = cell + " { background-color: " + color + "; }"

на

cell.style.backgroundColor = "red";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...