У випадку делегованих обробників подій, де у вас може бути щось подібне:
<ul>
<li data-id="1">
<span>Item 1</span>
</li>
<li data-id="2">
<span>Item 2</span>
</li>
<li data-id="3">
<span>Item 3</span>
</li>
<li data-id="4">
<span>Item 4</span>
</li>
<li data-id="5">
<span>Item 5</span>
</li>
</ul>
і ваш JS-код так:
$(document).ready(function() {
$('ul').on('click li', function(event) {
var $target = $(event.target),
itemId = $target.data('id');
//do something with itemId
});
});
Ви, швидше за все, виявите, що itemId є undefined
, оскільки вміст LI загорнуто в <span>
, що означає, що <span>
, ймовірно, буде ціллю події. Ви можете обійти це за допомогою невеликого чека, як-от так:
$(document).ready(function() {
$('ul').on('click li', function(event) {
var $target = $(event.target).is('li') ? $(event.target) : $(event.target).closest('li'),
itemId = $target.data('id');
//do something with itemId
});
});
Або, якщо ви віддаєте перевагу максимальної читабельності (а також уникнути зайвого повторення завершувальних викликів jQuery):
$(document).ready(function() {
$('ul').on('click li', function(event) {
var $target = $(event.target),
itemId;
$target = $target.is('li') ? $target : $target.closest('li');
itemId = $target.data('id');
//do something with itemId
});
});
Використовуючи делегування подій, цей .is()
метод є неоціненним для перевірки того, що ваша мета події (крім іншого) насправді є такою, якою вона вам потрібна. Використовуйте .closest(selector)
для пошуку дерева DOM та використовуйте .find(selector)
(як правило, у поєднанні з .first()
, як у .find(selector).first()
) для пошуку вниз. Вам не потрібно користуватися .first()
при використанні .closest()
, оскільки він повертає лише перший збіг елемента-предка, а .find()
повертає всіх відповідних нащадків.