Eu tenho esse layout que foi criado dinamicamente:
for (let i = 1; i < 10; i++) {
document.querySelector('.card-body').innerHTML += `<div class="row" id="img_div">
<div class="col-12 col-sm-12 col-md-2 text-center">
<img src="http://placehold.it/120x80" alt="prewiew" width="120" height="80">
</div>
<div id="text_div" class="col-12 text-sm-center col-sm-12 text-md-left col-md-6">
<h4 class="name"><a href="#" id="title` + i + `">Name</a></h4>
<h4>
<small>state</small>
</h4>
<h4>
<small>city</small>
</h4>
<h4>
<small>zip</small>
</h4>
</div>
<div class="col-12 col-sm-12 text-sm-center col-md-4 text-md-right row">
</div>
</div>
`
document.getElementById("title" + i).addEventListener('click', function() {
console.log(i)
});
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="card-body">
<!-- person -->
</div>
E quero obter o evento, clique em cada um h4 class="name"
e mostre um log com o número i
relacionado.
No entanto, console.log
mostra apenas o último i
relacionado ( i=9
neste caso) e não funciona com os outros i
números. Por que isso acontece? O que eu tenho que fazer?
javascript
html
innerhtml
Luiz Adorno
fonte
fonte
for
loop chamar um método para aplicar eventos a esses elementos, mas eu não sei. jsFiddle para testar..card-body
e verifique se o elemento (target
) é uma âncora e um ID que começam comtitle
.innerHTML += ...
matando os ouvintes de eventos definidos anteriormente, não o encerramento. Use emdocument.createElement
vez disso. Veja este tópicoRespostas:
innerHTML
redesenha o html completo, como resultado, todos os eventos anexados anteriormente são perdidos. UsarinsertAdjacentHTML()
fonte
insertAdjacentHTML
- todos os dias um dia de escola, muito bom.document.getElementById
imediatamente após adicionar o HTML. Se você estiver adicionando centenas de elementos, isso é muito trabalhoso.name
e participaria do evento apenas nessa classe enquanto passava pelo elemento (ou talvez apenas lendo o próprio evento) seria mais eficiente?document.createElement
puder ser usado, acho que geralmente é a melhor abordagem de linha de base. Outra possível melhoria para este post é usar dois loops: um para criar todo o HTML e outro para pegar todos os elementos usando uma classe em umadocument.querySelectorAll
chamada e adicionar os ouvintes do evento.Usar
+=
oninnerHTML
destrói ouvintes de eventos nos elementos dentro do HTML. A maneira correta de fazer isso é usardocument.createElement
. Aqui está um exemplo completo e mínimo:Obviamente, isso
document.getElementById
não é necessário aqui, pois acabamos de criar o objeto no bloco de loop. Isso economiza caminhadas em árvores potencialmente caras.Se você tiver blocos arbitrários de HTML com strings, como no seu exemplo, poderá usá-los
createElement("div")
, definainnerHTML
uma vez para o bloco e adicione ouvintes conforme necessário. Em seguida, acrescente os divs como filhos do seu elemento container.fonte
<div>
, entãodiv.innerHTML += yourHugeChunkOfHTML
. Portanto, não há razão para que isso não funcione em nenhum caso de uso.