동적으로 생성 된 목록에 html 데이터를 동적으로 삽입하려고하지만 동적으로 생성 된 버튼에 대한 onclick 이벤트를 첨부하려고하면 이벤트가 발생하지 않습니다. 솔루션은 정말 감사하겠습니다.
자바 스크립트 코드 :
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('btnSubmit').addEventListener('click', function () {
var name = document.getElementById('txtName').value;
var mobile = document.getElementById('txtMobile').value;
var html = '<ul>';
for (i = 0; i < 5; i++) {
html = html + '<li>' + name + i + '</li>';
}
html = html + '</ul>';
html = html + '<input type="button" value="prepend" id="btnPrepend" />';
document.getElementsByTagName('form')[0].insertAdjacentHTML('afterend', html);
});
document.getElementById('btnPrepend').addEventListener('click', function () {
var html = '<li>Prepending data</li>';
document.getElementsByTagName('ul')[0].insertAdjacentHTML('afterbegin', html);
});
});
HTML 코드 :
<form>
<div class="control">
<label>Name</label>
<input id="txtName" name="txtName" type="text" />
</div>
<div class="control">
<label>Mobile</label>
<input id="txtMobile" type="text" />
</div>
<div class="control">
<input id="btnSubmit" type="button" value="submit" />
</div>
</form>
답변
이는 요소가 동적으로 생성되기 때문입니다. 이벤트 를 처리 하려면 이벤트 위임 을 사용해야합니다 .
document.addEventListener('click',function(e){
if(e.target && e.target.id== 'brnPrepend'){
//do something
}
});
jquery는 다음을 더 쉽게 만듭니다.
$(document).on('click','#btnPrepend',function(){//do something})
이벤트 위임 이벤트 위임 기사에 대한 기사입니다.
답변
클릭을 캡처 document.body
한 다음 이벤트 대상을 확인 하는 해결 방법이 있습니다 .
document.body.addEventListener( 'click', function ( event ) {
if( event.srcElement.id == 'btnSubmit' ) {
someFunc();
};
} );
답변
요소를 삽입 한 후에 이벤트를 첨부해야합니다. 예를 들어 글로벌 이벤트를 삽입하지 않고 document
삽입 된 요소에 특정 이벤트를 첨부하는 것과 같습니다 .
예 :
document.getElementById('form').addEventListener('submit', function(e) {
e.preventDefault();
var name = document.getElementById('txtName').value;
var idElement = 'btnPrepend';
var html = `
<ul>
<li>${name}</li>
</ul>
<input type="button" value="prepend" id="${idElement}" />
`;
/* Insert the html into your DOM */
insertHTML('form', html);
/* Add an event listener after insert html */
addEvent(idElement);
});
const insertHTML = (tag = 'form', html, position = 'afterend', index = 0) => {
document.getElementsByTagName(tag)[index].insertAdjacentHTML(position, html);
}
const addEvent = (id, event = 'click') => {
document.getElementById(id).addEventListener(event, function() {
insertHTML('ul', '<li>Prepending data</li>', 'afterbegin')
});
}
<form id="form">
<div>
<label for="txtName">Name</label>
<input id="txtName" name="txtName" type="text" />
</div>
<input type="submit" value="submit" />
</form>
답변
차이점은 DOM에서 요소를 만들고 추가하는 방법에 있습니다.
를 통해 요소를 만드는 경우 document.createElement
이벤트 리스너를 추가하고 DOM에 추가합니다. 이벤트가 시작됩니다.
다음과 같은 문자열로 요소를 생성하는 경우 : html + = “<li> test </ li>”`, 요소는 기술적으로 문자열입니다. 문자열은 이벤트 리스너를 가질 수 없습니다.
한 가지 해결책은 각 요소를 생성 document.createElement
한 다음 DOM 요소에 직접 추가하는 것입니다.
// Sample
let li = document.createElement('li')
document.querySelector('ul').appendChild(li)
답변
다음과 유사한 작업을 수행 할 수 있습니다.
// Get the parent to attatch the element into
var parent = document.getElementsByTagName("ul")[0];
// Create element with random id
var element = document.createElement("li");
element.id = "li-"+Math.floor(Math.random()*9999);
// Add event listener
element.addEventListener("click", EVENT_FN);
// Add to parent
parent.appendChild(element);
답변
var __ = function(){
this.context = [];
var self = this;
this.selector = function( _elem, _sel ){
return _elem.querySelectorAll( _sel );
}
this.on = function( _event, _element, _function ){
this.context = self.selector( document, _element );
document.addEventListener( _event, function(e){
var elem = e.target;
while ( elem != null ) {
if( "#"+elem.id == _element || self.isClass( elem, _element ) || self.elemEqal( elem ) ){
_function( e, elem );
}
elem = elem.parentElement;
}
}, false );
};
this.isClass = function( _elem, _class ){
var names = _elem.className.trim().split(" ");
for( this.it = 0; this.it < names.length; this.it++ ){
names[this.it] = "."+names[this.it];
}
return names.indexOf( _class ) != -1 ? true : false;
};
this.elemEqal = function( _elem ){
var flg = false;
for( this.it = 0; this.it < this.context.length; this.it++ ){
if( this.context[this.it] === _elem && !flg ){
flg = true;
}
}
return flg;
};
}
function _( _sel_string ){
var new_selc = new __( _sel_string );
return new_selc;
}
이제 다음과 같은 이벤트를 등록 할 수 있습니다.
_( document ).on( "click", "#brnPrepend", function( _event, _element ){
console.log( _event );
console.log( _element );
// Todo
});
브라우저 지원
chrome-4.0, Edge-9.0, Firefox-3.5 Safari-3.2, Opera-10.0 이상
답변
이를 돕기 위해 작은 라이브러리를 만들었습니다. GitHub의 라이브러리 소스
<script src="dynamicListener.min.js"></script>
<script>
// Any `li` or element with class `.myClass` will trigger the callback,
// even elements created dynamically after the event listener was created.
addDynamicEventListener(document.body, 'click', '.myClass, li', function (e) {
console.log('Clicked', e.target.innerText);
});
</script>
기능은 jQuery.on ()과 유사합니다.
라이브러리는 Element.matches () 메서드를 사용 하여 지정된 선택기에 대해 대상 요소를 테스트합니다. 이벤트가 트리거되면 대상 요소가 지정된 선택자와 일치하는 경우에만 콜백이 호출됩니다.