[js/javaScript] 사이트에 어울리는 커스텀 Confirm 창 구현:Promise 사용(컨펌 창 구현1)
✓ 해당 버전에는 키보드 제어 관련된 버그가 있습니다. 디벨롭한 버전을 보고 싶다면 다음 링크를 클릭해주세요 ✓
https://cocoseom.tistory.com/7
[js/javaScript] 컨펌 창 구현2( + 키보드 제어): custom confirm(keyDown handle)
이번 포스팅은 전에 작성했던 자바스크립트로 컨펌 창 구현하기의 디벨롭 버전이다. https://cocoseom.tistory.com/4 [js/javaScript] 컨펌 창 구현하기: custom confirm javascript의 confirm() 함수는 강력합니다. 하
cocoseom.tistory.com
javascript의 confirm() 함수는 강력합니다. 하지만 솔직히 말해서 시각적으로 눈에 잘 안들어오고, 사이트와 어울리지 않는 경우가 많습니다. 때문에 커스텀 해달라는 요청이 발생하기도 합니다. 오늘은 이러한 경우에 어떻게 구현할 수 있는지 적어보겠습니다.
목차
- 문제발생: callback 함수와 javascript 내장함수와의 문제
- 1번 문제 해결
0. 구현 순서
가. 대화 상자를 HTML 요소로 생성(동적)
나. HTML 요소를 body 요소의 하위 요소로 추가합니다.
다. 모달창의 위치 중앙 설정
라. 배경을 회색으로 덮어서 모달 창을 띄웠을 때 다른 요소들을 클릭할 수 없도록 제어
마. 확인 버튼을 클릭했을 때 이벤트
바. 취소 버튼을 클릭했을 때 이벤트 설정
사. 회색 영역 클릭할 때 창을 닫도록 이벤트 추가
1. 콜백(callback)로 구현
See the Pen Untitled by My study Storage (@Eunbi13) on CodePen.
- 문제발생: callback 함수와 javascript 내장함수와의 문제
어떤 점이 문제가 될까?
이 방법으로는 Click_bth() 함수 내부나 혹시 그 다음 코드에 alert(), confirm() 같이 javascript 내장함수를 사용하는 경우, 팝업창이 닫히지 않고, alert()창이 떴습니다. callback함수보다 먼저 alert()이 실행되었습니다.
See the Pen Untitled by My study Storage (@Eunbi13) on CodePen.
이 문제가 발생한 이유는 alert()과 confirm() 함수가 호출될 때 브라우저에서 코드 실행을 멈추고, 사용자가 대화 상자에 응답할 때까지 기다리기 때문입니다. 이러한 대화 상자는 사용자와 상호작용하거나 정보를 제공하기 위해 브라우저에서 팝업 창으로 나타납니다.
또한, customConfrim() 함수에서 호출하는 콜백 함수는 비동기적으로 실행됩니다. 그렇기 때문에 alert() 함수가 먼저 호출되고, 그 다음에 콜백 함수가 실행됩니다.
따라서 이러한 문제를 해결하기 위해서는 비동기적인 콜백 함수를 사용하고, 대화 상자를 최대한 간단하고 직관적으로 구성하여 사용자 경험에 영향을 미치지 않도록 해야 합니다.
2. Promise와 return값을 받아서 구현
See the Pen Untitled by My study Storage (@Eunbi13) on CodePen.
이전과 같이, alert() 함수가 팝업 창이 닫히기 전에 호출되는 것이 아니라, 이제는 팝업 창이 닫힌 후에 alert() 함수가 호출됩니다.
return new Promise(function(resolve){})는 Promise 객체를 생성하고, 해당 객체가 처리하는 비동기 작업이 완료될 때 호출되는 콜백 함수(resolve)를 인자로 받습니다. 이 함수는 비동기 작업을 처리하고, 작업이 완료되면 resolve 함수를 호출하여 Promise 객체가 처리 결과를 반환할 수 있도록 합니다.
즉, Promise 객체가 처리 결과를 반환하려면 비동기 작업이 완료되어야 하므로, 이를 위해 비동기 작업의 결과를 처리할 수 있는 콜백 함수(resolve)를 Promise 객체가 생성될 때 함께 전달하는 것입니다. 이후 비동기 작업이 완료되면 resolve 함수를 호출하여 처리 결과를 반환합니다.
이 반환된 정보를 처리하기 위해 콜백 함수 대신 then() 메서드를 사용합니다. then() 메서드는 Promise 객체가 처리를 완료하면 호출되는 비동기 함수입니다.
정리하자면, Promise 객체를 반환하는 함수는 동기적으로 작동하지만, then() 메서드에서 처리하는 비동기 작업은 비동기적으로 처리됩니다. 여전히 alert()창이 버튼의 글자가 바뀌는 것보다 빨리 실행되는 이유죠.
쉽게 말해 함수가 호출되면 즉시 실행이 완료되었지만, 반환된 Promise 객체는 비동기 작업이 완료될 때까지 대기합니다. 이후 then() 메서드가 호출되어 처리 결과를 진행하는 것이죠.
설명이 되었나요?
마지막으로 javaScript 전문을 올리면서 글을 마치겠습니다. 봐주셔서 감사합니다.
function customConfirm(message, callback) {
// 대화 상자를 HTML 요소로 생성(동적)
var confirmBox = document.createElement('div');
confirmBox.setAttribute('class', 'confirm-box');
confirmBox.innerHTML = '<p>' + message + '</p><button class="confirm">확인</button><button class="cancel">취소</button>';
// HTML 요소를 body 요소의 하위 요소로 추가합니다.
document.body.appendChild(confirmBox);
// 모달창의 위치 중앙 설정
confirmBox.style.position = 'fixed';
confirmBox.style.top = '50%';
confirmBox.style.left = '50%';
confirmBox.style.transform = 'translate(-50%, -50%)';
confirmBox.style.zIndex = 999;
// 배경을 회색으로 덮어서 모달 창을 띄웠을 때 다른 요소들을 클릭할 수 없도록 제어
var overlay = document.createElement('div');
overlay.setAttribute('class', 'overlay');
document.body.appendChild(overlay);
overlay.style.position = 'fixed';
overlay.style.top = '0';
overlay.style.left = '0';
overlay.style.width = '100%';
overlay.style.height = '100%';
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
overlay.style.zIndex = '998';
return new Promise(function(resolve) {
// 확인 버튼을 클릭했을 때 이벤트
var confirmButton = document.querySelector('.confirm');
confirmButton.addEventListener('click', function() {
// 확인 버튼을 눌렀을 때 resolve 메서드를 호출
document.body.removeChild(confirmBox);
document.body.removeChild(overlay);
setTimeout(function() {
resolve(true);
}, 100);
});
// 취소 버튼을 클릭했을 때 이벤트
var cancelButton = document.querySelector('.cancel');
cancelButton.addEventListener('click', function() {
// 취소 버튼을 눌렀을 때 resolve 메서드를 호출
document.body.removeChild(confirmBox);
document.body.removeChild(overlay);
setTimeout(function() {
resolve(false);
}, 100);
});
// 회색 영역 클릭할 때 창을 닫도록 이벤트 추가
overlay.addEventListener('click', function() {
document.body.removeChild(confirmBox);
document.body.removeChild(overlay);
});
});
}
// 함수 호출
function Click_bth(message){
customConfirm(message)
.then(function(result){
if (result) {
//"확인 클릭";
} else {
//"취소 클릭";
}
});
}
✓ 해당 버전에는 키보드 제어 관련된 버그가 있습니다. 디벨롭한 버전을 보고 싶다면 다음 링크를 클릭해주세요 ✓