Nel caso dei gestori di eventi delegati, dove potresti avere qualcosa del genere:
<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 il tuo codice JS in questo modo:
$(document).ready(function() {
$('ul').on('click li', function(event) {
var $target = $(event.target),
itemId = $target.data('id');
//do something with itemId
});
});
Molto probabilmente scoprirai che itemId è undefined
, poiché il contenuto di LI è racchiuso in a <span>
, il che significa <span>
che probabilmente sarà il target dell'evento. Puoi aggirare questo problema con un piccolo segno di spunta, in questo modo:
$(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
});
});
Oppure, se si preferisce massimizzare la leggibilità (ed anche evitare inutili ripetizioni delle chiamate di wrapping 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
});
});
Quando si utilizza la delega di eventi, il .is()
metodo è prezioso per verificare che il target dell'evento (tra le altre cose) sia effettivamente ciò che è necessario. Usare .closest(selector)
per cercare l'albero del DOM e usare .find(selector)
(generalmente accoppiato con .first()
, come in .find(selector).first()
) per cercarlo. Non è necessario utilizzarlo .first()
durante l'utilizzo .closest()
, poiché restituisce solo il primo elemento antenato corrispondente, mentre .find()
restituisce tutti i discendenti corrispondenti.