본문 바로가기
JavaScript

오늘 하루 그만 보기 모달 윈도 구현하기(feat.Cookie)

by Vintz 2022. 8. 18.
반응형

마케팅 회사의 개발자로 일하다보니 꽤 많은 온라인 쇼핑몰에서 모달 윈도를 다양하게 활용하고 있다는 것을 알게 되었습니다. 특히 사용자의 구매 유도를 위한 배너 광고 형식을 자주 보는 것 같아요. 배너 광고 형식 외에도 프로모션 알림, 공지사항 등이 있겠네요. 여기엔 '오늘 하루 그만 보기', '3일 동안 보지 않기'와 같은 기능도 포함이 되어 있습니다. 이러한 기능은 어떻게 구현을 하는지 해당 기능을 중심으로 알아보겠습니다.

왜 쿠키(Cookie)일까?

'오늘 하루 그만 보기'와 같은 기능은 대부분 쿠키를 통해서 구현을 합니다. 현재 네이버의 프로모션 알림도 쿠키를 통해 제어를 하고있습니다.

네이버 프로모션 알림 - https://www.naver.com/

확인하는 방법은 개발자 도구를 켜서 애플리케이션 탭의 쿠키에서 확인을 하실 수 있습니다. 네이버에서 '3일 동안 보지 않기'를 클릭한 후 쿠키를 확인해보세요.

1.개발자도구 2.애플리케이션 3.쿠키에서 확인하실 수 있습니다.

데이터의 생명주기(Life Cycle)

쿠키는 방문한 웹사이트에서 생성되는 파일로, 사용자의 웹 경험을 개인화 하는 데 사용됩니다. Web Storage API도 목적은 같지만, 데이터의 생명주기에 차이가 있습니다.

쿠키(Cookie)

  • 지정한 만료기한까지 데이터를 저장합니다. 
    • 새로고침, 브라우저의 탭을 닫거나 껐다 켜도 데이터가 유지됩니다.
    • 만료일이 되면 삭제됩니다.
  • 크롬 기준 만료기한을 지정하지 않을 경우, 브라우저를 닫으면(모든 탭을 닫으면) 삭제됩니다.
    • 엣지의 경우 브라우저를 종료해야 삭제됩니다.
    • 이런 쿠키를 세션 쿠키(session cookie)라고 부릅니다.
    • 또는 임시 쿠키(temporary cookie), 비영구 쿠키(non-persistent cookie)라고도 합니다.

세션스토리지(SessionStorage)

  • 세션에 한정해, 즉 브라우저나 탭이 닫힐 때까지만 데이터를 저장합니다.

로컬스토리지(LocalStorage)

  • 만료기한 없이 데이터를 저장합니다.
    • 자바스크립트를 사용하거나 브라우저 캐시 또는 로컬 저장 데이터를 지워야만 삭제가 됩니다.

따라서 만료기한을 정할 수 있는 쿠키가 현재 사용목적에 더 부합하겠네요.

구현하기

먼저 쿠키 사용을 위한 함수를 구현하겠습니다. 주어진 이름의 쿠키를 반환하는 함수와 현재 경로(path=/)를 기본으로, 주어진 이름과 값 그리고 만료기한까지 갖는 쿠키를 설정하는 함수가 필요합니다.

getCookie(name)

function getCookie(name) {
  // 조건에 맞는 쿠키가 없다면 undefined를 반환합니다.
  const encodeName = encodeURIComponent(name);
  const matches = document.cookie.match(new RegExp(
    "(?:^|; )" + encodeName.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
  ));
  
  return matches ? decodeURIComponent(matches[1]) : undefined;
}

setCookie(name, value, days)

function setCookie(name, value, days) {
  let expires = '';
  // 형식의 유효성을 일관성 있게 유지하기 위해 내장 함수 encodeURIComponent를 사용하여 이름과 값을 이스케이프 처리해줍니다.
  // e.g. 'hello world' -> 'hello%20world', 'test?' -> 'test%3F'
  const updatedCookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);

  if (days) {
    const date = new Date();
    date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
    // 쿠키의 유효 일자는 반드시 GMT(Greenwich Mean Time) 포맷으로 설정해야 합니다.
    // date.toUTCString을 사용하면 해당 포맷으로 쉽게 변경할 수 있습니다.
    expires = `; expires=${date.toUTCString()}`;
  }
  document.cookie = `${updatedCookie}${expires}; path=/`;
}

여기서 주의할 점은, setCookie 함수는 쿠키의 name과 value를 인코딩하여 설정했다는 점입니다. 따라서 getCookie 함수도 그에 맞는 처리를 해주었습니다. 그럼 이제 기능 구현을 통해서 적용을 해보겠습니다.

 

쿠키를 어떻게 제어를 해야 사용자가 원하는 방향으로 이끌 수 있을까요? 제가 생각한 방식은 다음과 같습니다.

  1. 모달 윈도의 초기 상태는 display: none으로 한다.
  2. 만약 'modal' 쿠키가 없으면 모달 윈도를 노출시킨다.
  3. '오늘 하루 그만 보기' 버튼 클릭 시 하루 동안 유지되는 'modal' 쿠키를 설정한다.
  4. 닫기 버튼이나 모달 윈도 밖을 클릭하면 모달 윈도가 닫힌다.

이런 흐름이라면 새로고침을 연속으로 해도 깜빡임 없이 작동을 할 것입니다.

'use strict';
import { setCookie, getCookie } from './cookie.js';

const modalWrapper = document.querySelector('.modal-wrapper');

if (!getCookie('modal')) {
  modalWrapper.classList.add('flex');
}

const onClose = (target) => {
  if (target.id === 'closeToday') {
    setCookie('modal', 1, 1);
  }

  modalWrapper.classList.remove('flex');
  modalWrapper.classList.add('hidden');
};

modalWrapper.onclick = (event) => {
  const target = event.target;
  const condition = target.tagName === 'BUTTON' || target.classList.contains('modal-wrapper');

  if (!condition) {
    return;
  }

  onClose(target);
};

결론

이 글을 통해 왜 '오늘 하루 그만 보기'와 같은 기능들은 쿠키를 사용하는지, 쿠키의 데이터 생명주기는 다른 선택지와 어떻게 다른지 알아보고 기능 구현까지 해보았습니다. 저는 직접 구현을 해보면서 쿠키에 대해 어느 정도 감도 잡히고 재미도 있었는데요. 이 글을 읽는 독자분들도 도움이 되었으면 좋겠습니다.

 

전체 코드는 깃허브 저장소에서 보실 수 있습니다.

참고

쿠키와 document.cookie - 모던 JavaScript 튜토리얼
이벤트 위임 - 모던 JavaScript 튜토리얼
반응형