No caso de manipuladores de eventos delegados, onde você pode ter algo parecido com isto:
<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>
e seu código JS assim:
$(document).ready(function() {
$('ul').on('click li', function(event) {
var $target = $(event.target),
itemId = $target.data('id');
//do something with itemId
});
});
É mais provável que você encontre esse itemId undefined
, pois o conteúdo do LI está envolvido em um <span>
, o que significa <span>
que provavelmente será o destino do evento. Você pode contornar isso com uma pequena verificação, assim:
$(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
});
});
Ou, se você preferir maximizar a legibilidade (e também evitar a repetição desnecessária de chamadas de quebra automática de 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
});
});
Ao usar a delegação de eventos, o .is()
método é inestimável para verificar se o destino do seu evento (entre outras coisas) é realmente o que você precisa. Use .closest(selector)
para pesquisar na árvore do DOM e use .find(selector)
(geralmente associado a .first()
, como em .find(selector).first()
) para pesquisá-la. Você não precisa usá-lo .first()
ao usá- .closest()
lo, pois ele retorna apenas o primeiro elemento ancestral correspondente, enquanto .find()
retorna todos os descendentes correspondentes.