이전에 기본적인 팝업 UI 컴포넌트를 직접 구현해보며, 팝업 구조와 작동 방식을 익혔습니다.
이번에는 그 연장선으로 팝업을 실생활에 응용하는 방식을 고민해보았고,
"사용자의 관심을 끌 수 있는 간단한 인터랙션"을 목표로 MBTI 설문 팝업을 만들어보았습니다.
친구들과 팝업 스터디를 하면서 느낀 제 생각하기에는 팝업은 보통 일회성이 강하고, 사용자 주목을 빠르게 끌어야 하는 요소라고 생각했습니다.
그래서 짧고 직관적인 질문과 함께, 결과를 두 번째 팝업으로 출력하는 구조를 통해 더욱 집중도 있게 표현할 수 있도록 구성해 보았습니다.
설문 버튼을 누르면 질문 팝업 → MBTI 선택 → 결과 팝업으로 이동
팝업 UI와 자바스크립트 이벤트 연결을 통해 JavaScript 기초 개념을 연습할 수 있었습니다.
설문 시작 -> 질문 팝업 -> 결과 팝업 -> 닫기
버튼 클릭시 MBTI 질문 팝업이 열리고, 외향성 / 내향성 하나 선택 가능하도록 선택지 제공합니다.
선택에 따라 결과 문구 표시하여 정보를 제공하고 닫기 버튼 클릭시 해당 창이 닫힙니다.
<div class="modal" id="surveyModal">
<div class="modal_popup">
<h3>🤔 MBTI 간단 설문</h3>
<div class="subtext">Q. 휴식시간이 생긴다면 어떤 게 더 흥미롭나요?</div>
<div class="button_group">
<button class="gray_btn mbti_btn" data-type="I">혼자 즐기는 취미생활</button>
<button class="red_btn mbti_btn" data-type="E">사람들과 함께 놀이공원</button>
</div>
</div>
</div>
<!-- 결과 팝업 -->
<div class="modal" id="resultModal">
<div class="modal_popup">
<h3>✨ 결과 도착!</h3>
<div class="result_text" id="resultText">MBTI 결과가 여기에 표시됩니다.</div>
<div class="button_group">
<button class="gray_btn" id="resultCloseBtn">닫기</button>
</div>
</div>
</div>
data-type="I" / "E" 같은 속성은 JavaScript에서 어떤 값을 클릭했는지 구분하기 위해 사용함
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: $overlay-color;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal_popup {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: $popup-bg-color;
border-radius: 8px;
width: 400px;
padding: 24px 24px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
border-top: 4px solid $line-red;
// 응용
.result_text {
font-size: 1rem;
font-weight: 500;
text-align: left;
color: $popup-subtitle-color;
margin-top: 24px;
margin-bottom: 24px;
}
h3 {
color: $popup-title-color;
margin-bottom: 16px;
font-size: 1.2rem;
}
.subtext {
color: $popup-subtitle-color;
font-size: 0.85rem;
margin-top: 24px;
margin-bottom: 24px;
line-height: 1.5;
}
.button_group {
display: flex;
justify-content: flex-end;
gap: 10px;
button {
padding: 8px 18px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
&.gray_btn {
background-color: $btn-gray;
color: #fff;
}
&.red_btn {
background-color: $btn-red;
color: #fff;
}
}
}
}
이번에 응용 연습하는 것으로 컬러가 다양하지 않기 때문에 반복되는 색상을 고려했습니다.
$popup-subtitle-color 같은 변수는 Sass 문법으로, 반복되는 색상 관리를 해봄
const openBtn = document.querySelector('.modal_btn');
const surveyModal = document.getElementById('surveyModal');
const resultModal = document.getElementById('resultModal');
const mbtiBtns = document.querySelectorAll('.mbti_btn');
const resultText = document.getElementById('resultText');
const resultCloseBtn = document.getElementById('resultCloseBtn');
// 설문 열기
openBtn.addEventListener('click', () => {
surveyModal.style.display = 'flex';
});
// 바깥 클릭 시 닫기 (설문)
surveyModal.addEventListener('click', (e) => {
if (e.target === surveyModal) {
surveyModal.style.display = 'none';
}
});
// 바깥 클릭 시 닫기 (결과)
resultModal.addEventListener('click', (e) => {
if (e.target === resultModal) {
resultModal.style.display = 'none';
}
});
// 설문 결과 클릭 시 → 설문 닫기, 결과 팝업 열기
mbtiBtns.forEach((btn) => {
btn.addEventListener('click', () => {
const type = btn.dataset.type;
let message = '';
if (type === 'I') {
message = '😌 당신은 내향형 (I) 혼자만의 시간에서 에너지를 얻어요.';
} else {
message = '😄 당신은 외향형 (E) 사람들과 함께일 때 더 활발해요!';
}
surveyModal.style.display = 'none';
resultText.textContent = message;
resultModal.style.display = 'flex';
});
});
// 결과 팝업 닫기
resultCloseBtn.addEventListener('click', () => {
resultModal.style.display = 'none';
});
const openBtn = document.querySelector('.modal_btn');
const surveyModal = document.getElementById('surveyModal');
const resultModal = document.getElementById('resultModal');
const mbtiBtns = document.querySelectorAll('.mbti_btn');
const resultText = document.getElementById('resultText');
const resultCloseBtn = document.getElementById('resultCloseBtn');
HTML 안에 있는 버튼들과 팝업 창을 JavaScript에서 제어하기 위해 연결
코드 설명
querySelector() 클래스, 태그, ID 등 하나의 요소를 선택해요 (CSS 선택자 방식)
getElementById() HTML에서 ID가 있는 요소를 선택할 때 사용해요
querySelectorAll() 조건에 맞는 모든 요소를 배열처럼 선택해요 (여기선 버튼 2개)
const 선택한 요소를 저장하는 변수예요. 값을 바꾸지 않기 때문에 const를 사용했어요
openBtn.addEventListener('click', () => {
surveyModal.style.display = 'flex';
});
사용자가 .modal_btn 설문시작 버튼을 클릭하면 surveymodal이라는 팝업을 보여줌
팝업은 처음에 display : none으로 숨겨져 있다가, display : flex로 바뀌면서 화면에 보이게 하여 설문 팝업을 열어주었다.
mbtiBtns.forEach((btn) => {
btn.addEventListener('click', () => {
const type = btn.dataset.type;
let message = '';
여러 버튼을 하나씩 돌면서 이벤트를 붙여주기 위해서 forEach를 사용해 주었고,
btn.dataset.type="i"/"e"처럼 데이터 구분하기 위해 적어놓은 값을 불러옵니다.
if (type === 'I') {
message = '😌 당신은 내향형 (I) 혼자만의 시간에서 에너지를 얻어요.';
} else {
message = '😄 당신은 외향형 (E) 사람들과 함께일 때 더 활발해요!';
}
surveyModal.style.display = 'none';
resultText.textContent = message;
resultModal.style.display = 'flex';
});
});
textContent = message 는 .result_text 안의 글자 내용을 해당 메세지로 바꿔주는 기능입니다.
결론적으로 설문 팝업은 닫히고 결과 팝업이 열리면서 선택한 타입에 따라 메세지(결과값)이 표시되는 것을 보여줍니다.
1) 요소 선택(document.querySelector / getElementById)
2) 이벤트 연결(addEventListener)
3) 조건문(if)
4) data-* 속성 사용법 (dataset)
5) HTML 스타일 제어(style.display)
6) 배열 반복(forEach)
등등,,갈 길이 멉니다..ㅎ