Como fazer a ligação antecipada para manipulador de eventos em JavaScript? (exemplo com jQuery)
-
27-09-2019 - |
Pergunta
A ligação tardia de JavaScript é ótima. Mas como faço para me amarrar mais cedo quando quero?
Estou usando o jQuery para adicionar links com manipuladores de eventos em um loop a uma div. A variável 'atag' muda no loop. Quando clico nos links posteriormente, todos os links alertam a mesma mensagem, que é o último valor de 'atag'. Como faço para vincular uma mensagem de alerta diferente a todos os links?
Todos os links devem alertar com o valor que 'atag' teve quando o manipulador de eventos foi adicionado, não quando foi clicado.
for (aTag in tagList) {
if (tagList.hasOwnProperty(aTag)) {
nextTag = $('<a href="#"></a>');
nextTag.text(aTag);
nextTag.click(function() { alert(aTag); });
$('#mydiv').append(nextTag);
$('#mydiv').append(' ');
}
}
Solução
Você pode passar dados para o bind
método:
nextTag.bind('click', {aTag: aTag}, function(event) {
alert(event.data.aTag);
});
Isso fará uma cópia de aTag
, então cada manipulador de eventos terá valores diferentes para isso. Seu caso de uso é precisamente o motivo pelo qual esse parâmetro bind
existe.
Código completo:
for (aTag in tagList) {
if (tagList.hasOwnProperty(aTag)) {
nextTag = $('<a href="#"></a>');
nextTag.text(aTag);
nextTag.bind('click', {aTag: aTag}, function(event) {
alert(event.data.aTag);
});
$('#mydiv').append(nextTag);
$('#mydiv').append(' ');
}
}
Outras dicas
Você também pode fazer uma função de invólucro que leva o texto para alertar como um parâmetro e retorna o manipulador de eventos
function makeAlertHandler(txt) {
return function() { alert(txt); }
}
e substitua
nextTag.click(function() { alert(aTag); });
com
nextTag.click(makeAlertHandler(aTag));
Você precisa manter uma cópia dessa variável, como esta:
for (aTag in tagList) {
if (tagList.hasOwnProperty(aTag)) {
nextTag = $('<a href="#"></a>');
nextTag.text(aTag);
var laTag = aTag;
nextTag.click(function() { alert(laTag); });
$('#mydiv').append(nextTag);
$('#mydiv').append(' ');
}
}
o aTag
A variável está mudando cada vez que você loop, no final do loop, é deixado como o último item do loop. No entanto, cada uma das funções que você criou para este mesmo variável. Em vez disso, você deseja uma variável por, então faça uma cópia local como eu acima.
Você também pode diminuir muito isso com o encadeamento, mas sinto que ele obscurece o ponto neste caso, já que o problema é o escopo e as referências.