Como fazer a ligação antecipada para manipulador de eventos em JavaScript? (exemplo com jQuery)

StackOverflow https://stackoverflow.com/questions/2663594

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(' ');
  }
}
Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top