Jquery 로 .html() 을 사용하여 동적 HTML 삽입 시 기존 노드와 기존 이벤트 리스너가 삭제되지만
.on() 으로 등록했던 이벤트 리스너들은 Jquery 가 재 바인딩을 해줘 이벤트를 사용할 수 있었다.
하지만 vanilla JS 의 .innerHTML 을 통해 동적 HTML 삽입 시 기존 노드 및 기존 이벤트 리스너가 삭제된 후
.addEventListener() 를 통해 이벤트를 수동으로 재등록 해줘야 사용할 수 있다.
이때 vanilla JS 로 동적 HTML 삽입 시 이벤트 리스너 및 스크립트를 실행할 수 있는 방법은
공통 함수를 호출하여 함수 내 스크립트 태그내용을 불러와서 재등록 해주면 된다.
본인은 모달창을 띄울때 모달창 내용을 동적 HTML 삽입하여 띄웠다.
const initializeModalContent = function(modalElement, htmlContent, options = {}) {
// 1. 기본 옵션 설정
const defaultOptions = {
show: true,
backdrop: 'static',
keyboard: true,
focus: true
};
// 사용자 옵션과 기본 옵션 병합
const modalOptions = { ...defaultOptions, ...options };
// 2. 스크립트 태그들을 추출하고 내용 저장
const tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlContent;
const scripts = Array.from(tempDiv.getElementsByTagName('script'))
.map(script => ({
attributes: Array.from(script.attributes),
content: script.textContent
}));
// 3. HTML 콘텐츠 삽입
modalElement.innerHTML = htmlContent;
// 4. 스크립트 재생성 및 실행
scripts.forEach(script => {
if (!script.content) return;
const newScript = document.createElement('script');
script.attributes.forEach(attr => {
newScript.setAttribute(attr.name, attr.value);
});
newScript.textContent = script.content;
modalElement.appendChild(newScript);
});
// 5. 모달 표시 (옵션이 제공된 경우)
if (modalOptions.show) {
const modal = new bootstrap.Modal(modalElement, {
backdrop: modalOptions.backdrop,
keyboard: modalOptions.keyboard,
focus: modalOptions.focus
});
modal.show();
}
// 6. 모달 컨텐츠 로드 완료 이벤트 발생
modalElement.dispatchEvent(new CustomEvent('modalContentLoaded'));
};
이러한 함수를 사용하여 동적 HTML 파일 내 스크립트 내용을 재등록 해준다.
이때 동적 HTML 파일 내 document.addEventListener("DOMContentLoaded", () => {}) 를 제거해줘도
동적 HTML 파일 삽입 후 스크립트를 재등록해주면 사용이 가능하다.
// .innerHTML 을 통한 동적 HTML 삽입
document.getElementById('testDialog').innerHTML = response.data;
// 동적 HTML이 삽입된 DOM 호출
const modalElement = document.querySelector('#testDialog');
// 모달 공통 유틸리티
initializeModalContent(modalElement, response.data, {
backdrop: 'static',
keyboard: false
});
// HTML
<div class="modal draggable fade in" id="testDialog" tabindex="-1" role="modal" aria-hidden="true" >
</div>
.innerHTML 을 통해서 동적 HTML 파일을 삽입해주고 initializeModalContent 공통 함수로 스크립트를 재등록 해준다.
문제점 : 상위에 스크립트가 등록되어 있으면 DOM 이 그려지기 직전에 호출되면 호이스팅 문제로 에러가 발생한다.
이유는 상위의 스크립트 내용 중 DOM 이 그려진 후 호출되어야 하는 스크립트가 존재할 경우 에러가 발생한다.
해결하기 위해선 addEventListener('modalContentLoaded', () =>{}) 를 통해서
모달창 컨텐츠가 로드된 후 실행하도록 코드를 추가해주면 된다.
document.querySelector('#testDialog').addEventListener('modalContentLoaded', () => {
... 모달창이 로드된 후 실행될 코드
});