[javascript]팝업 응용하기 - MBTI 설문 팝업 만들기

jineeds·2025년 4월 4일
0

구현하기

목록 보기
2/6
post-thumbnail

👋 팝업 응용하기 Start

이전에 기본적인 팝업 UI 컴포넌트를 직접 구현해보며, 팝업 구조와 작동 방식을 익혔습니다.
이번에는 그 연장선으로 팝업을 실생활에 응용하는 방식을 고민해보았고,
"사용자의 관심을 끌 수 있는 간단한 인터랙션"을 목표로 MBTI 설문 팝업을 만들어보았습니다.

친구들과 팝업 스터디를 하면서 느낀 제 생각하기에는 팝업은 보통 일회성이 강하고, 사용자 주목을 빠르게 끌어야 하는 요소라고 생각했습니다.

그래서 짧고 직관적인 질문과 함께, 결과를 두 번째 팝업으로 출력하는 구조를 통해 더욱 집중도 있게 표현할 수 있도록 구성해 보았습니다.

설문 버튼을 누르면 질문 팝업 → MBTI 선택 → 결과 팝업으로 이동
팝업 UI와 자바스크립트 이벤트 연결을 통해 JavaScript 기초 개념을 연습할 수 있었습니다.

📌 목표

설문 시작 -> 질문 팝업 -> 결과 팝업 -> 닫기

버튼 클릭시 MBTI 질문 팝업이 열리고, 외향성 / 내향성 하나 선택 가능하도록 선택지 제공합니다.
선택에 따라 결과 문구 표시하여 정보를 제공하고 닫기 버튼 클릭시 해당 창이 닫힙니다.

✏ html 구조

<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에서 어떤 값을 클릭했는지 구분하기 위해 사용함

✏ scss 스타일링

.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 문법으로, 반복되는 색상 관리를 해봄

✏ JavaScript 흐름


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)

등등,,갈 길이 멉니다..ㅎ

profile
안 되는 이유보다 되는 방법부터 찾는 새싹

0개의 댓글