AJAX 요청 내에서 모달을 보여주고 닫으려고 할 때, 모달이 먹통이 되는 현상은 주로 타이밍 문제나 모달 초기화, 이벤트 처리 문제에서 비롯될 수 있습니다. 아래 단계별로 문제 해결을 위한 몇 가지 점검 및 개선 방안을 제시합니다.
1. AJAX 콜백 내에서 모달 제어
- 문제 원인:
AJAX 성공 콜백 내에서 setTimeout(closeModal, 1)과 같이 짧은 지연 후에 모달을 닫으려고 할 경우, 모달이 완전히 열리거나 초기화되기 전에 닫기 요청이 들어갈 수 있습니다.
- 해결 방안:
- 적절한 지연 시간 적용:
1ms 대신 모달 애니메이션과 초기화에 맞는 충분한 딜레이(예: 300~500ms)를 적용합니다.
- 이벤트 기반 처리:
모달의 hidden.bs.modal 이벤트를 활용하여 모달이 실제로 닫힌 후 후속 작업을 진행할 수 있습니다.
예를 들어, 아래와 같이 모달이 완전히 열린 후 AJAX 요청을 진행하는 방식과, AJAX 응답 후 모달을 닫을 때 약간의 지연을 주는 방식을 사용할 수 있습니다.
const modalEl = document.getElementById('processingModal');
let myModal = bootstrap.Modal.getInstance(modalEl);
if (!myModal) {
myModal = new bootstrap.Modal(modalEl, {
backdrop: 'static',
keyboard: false
});
}
// 모달을 보여주는 함수
function showModal() {
console.log("모달을 표시합니다.");
myModal.show();
}
// 모달을 닫는 함수 (지연 시간을 조금 늘림)
function closeModal() {
console.log("모달을 닫습니다.");
myModal.hide();
}
// 모달이 완전히 열린 후 AJAX 요청 실행 (shown.bs.modal 이벤트 사용)
modalEl.addEventListener('shown.bs.modal', function () {
// 서버로 변경사항 전송
$.ajax({
url: '/Menu/UpdateMenuTree',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(menuUpdates),
headers: {
'RequestVerificationToken': $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (response) {
if (response.success) {
treeModified = false;
const saveBtn = $('#saveTreeBtn');
saveBtn.removeClass('btn-danger').addClass('btn-success');
saveBtn.html('<i class="fas fa-save"></i> 변경사항 저장');
// 모달을 닫기 전 약간의 지연 (300ms 정도)
setTimeout(closeModal, 300);
} else {
alert('오류가 발생했습니다: ' + response.message);
}
},
error: function () {
myModal.hide();
alert('서버 요청 중 오류가 발생했습니다. 다시 시도해 주세요.');
}
});
});
// AJAX 요청 전에 모달을 보여줌 (약간의 지연 적용)
setTimeout(showModal, 300);