Существует два основных метода (без использования 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
, поэтому у меня нет беспокоиться о нескольких копиях моей функции обработки событий.
(супер-эксперты: оправдана ли моя паранойя? или каким-то образом анонимные функции объединяются в одну копию?)