Задать вопрос
JackShcherbakov
@JackShcherbakov

В чем заключается минус такого делегирования?

Здравствуйте!
Читаю эту статью про делегирования событий. Я никак не могу понять в чем минус такого подхода:
//имеется таблица, при клике на ячейки которой ячейки должны сменить цвет
var selectedTd;

table.onclick = function(event) {
  var target = event.target; // где был клик?

  if (target.tagName != 'TD') return; // не на TD? тогда не интересует

  highlight(target); // подсветить TD
};

function highlight(node) {
  if (selectedTd) {
    selectedTd.classList.remove('highlight');
  }
  selectedTd = node;
  selectedTd.classList.add('highlight');
}

Автор объясняет это так:

Однако, у текущей версии кода есть недостаток.

Клик может быть не на том теге, который нас интересует, а внутри него.

В нашем случае, если взглянуть на HTML таблицы внимательно, видно, что ячейка содержит вложенные теги, например <strong>:
<td>
  <strong>Northwest</strong>
  ...Metal..Silver..Elders...
</td>


И что дальше? Проверка if (target.tagName != 'TD') return; справляется со своей задчей - игнорирует все, кроме td. Вообще непонятно зачем эта беготня по иерархии когда все в одну строчку делается.
Автор предлагает такое решение:
table.onclick = function(event) {
  var target = event.target;

  // цикл двигается вверх от target к родителям до table
  while (target != table) {
    if (target.tagName == 'TD') {
      // нашли элемент, который нас интересует!
      highlight(target);
      return;
    }
    target = target.parentNode;
  }

  // возможна ситуация, когда клик был вне <td>
  // если цикл дошёл до table и ничего не нашёл,
  // то обработчик просто заканчивает работу
}


Заранее благодарю всех за ответ!
  • Вопрос задан
  • 276 просмотров
Подписаться 2 Простой Комментировать
Решения вопроса 1
rockon404
@rockon404
Frontend Developer
И что дальше? Проверка if (target.tagName != 'TD') return; справляется со своей задчей - игнорирует все, кроме td.

Так вы кликните по td, а попадете на вложенный элемент strong, вызов прервется и td не подсветится, так как
target == 'strong'
хотя вы кликнули по td.

Затем и нужна беготня по иерархии. Примерно так же делегирование jQuery работает:
$('table').on('click', 'td', function() { 
  //handler 
});

Там такая же "беготня" в реализации.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Stalker_RED
@Stalker_RED
Все действительно можно сделать в одну строчку.
table.onclick = function(event) {
	highlight(event.target.closest('td'))
}
https://jsfiddle.net/cm71Ljqa/

Хотя лучше в три: https://jsfiddle.net/cm71Ljqa/2/
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы