이 레이아웃은 동적으로 만들어졌습니다.
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>
그리고 각 이벤트를 클릭하고 관련 h4 class="name"
번호가있는 로그를 표시 하고 싶습니다 i
.
그러나 console.log
마지막 i
관련 항목 만 표시하고 ( i=9
이 경우) 다른 i
숫자 와는 작동하지 않습니다 . 왜 이런 일이 발생합니까? 어떻게해야합니까?
답변
innerHTML
이전에 연결된 모든 이벤트가 손실되므로 전체 HTML을 다시 그립니다. 사용하다insertAdjacentHTML()
for(let i=1;i<10;i++){
document.querySelector('.card-body').insertAdjacentHTML('beforeend',`<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>
답변
+=
on을 사용 innerHTML
하면 HTML 내부의 요소에서 이벤트 리스너가 제거됩니다. 이를 수행하는 올바른 방법은을 사용하는 것 document.createElement
입니다. 다음은 최소한의 완전한 예입니다.
for (let i = 1; i < 10; i++) {
const anchor = document.createElement("a");
document.body.appendChild(anchor);
anchor.id = "title" + i;
anchor.href= "#";
anchor.textContent = "link " + i;
document.getElementById("title" + i)
.addEventListener("click", e => console.log(i));
}
a {
margin-left: 0.3em;
}
물론, document.getElementById
우리는 루프 블록에서 객체를 생성했기 때문에 여기서는 필요하지 않습니다. 이로 인해 잠재적으로 값 비싼 트리 워크가 절약됩니다.
for (let i = 1; i < 10; i++) {
const anchor = document.createElement("a");
document.body.appendChild(anchor);
anchor.href= "#";
anchor.textContent = "link " + i;
anchor.addEventListener("click", e => console.log(i));
}
a {
margin-left: 0.3em;
}
예제와 같이 임의의 문자열 화 된 HTML 청크가있는 경우을 사용 createElement("div")
하여 innerHTML
한 번 청크에 설정하고 필요에 따라 리스너를 추가 할 수 있습니다 . 그런 다음 div를 컨테이너 요소의 자식으로 추가하십시오.
for (let i = 1; i < 10; i++) {
const rawHTML = `<div><a href="#" id="link-${i}">link ${i}</a></div>`;
const div = document.createElement("div");
document.body.appendChild(div);
div.href= "#";
div.innerHTML = rawHTML;
div.querySelector(`#link-${i}`)
.addEventListener("click", e => console.log(i));
}