2023.03.24 popupCookie로 쿠키만들기 및 만료시간 설정

이무헌·2023년 7월 19일
0

html,css,js

목록 보기
15/21
post-thumbnail

1.쿠기의 만료시간을 이용한 팝업 설정

1.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./index.css" />
  </head>
  <body>
    <div class="">
      <p>남은 시간: <span class="popup-time"></span></p>
    </div>
    <div class="popup-wrap">
      <div class="popup">
        <div class="popup-header">
          <span class="popup-btn"></span>
        </div>
        <div class="popup-body">
          <button class="event-btn">클릭</button>
        </div>
      </div>
    </div>
  </body>
  <script src="./index.js"></script>
</html>

2.css

.popup-wrap {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  background-color: rgba(0, 0, 0, 0.4);
  display: none;
}

.is-on{
    display: block;
}

.popup-wrap .popup {
  position: absolute;
  width: 400px;
  height: 600px;
  background-color: white;
  border-radius: 20px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.popup-wrap .popup .popup-btn {
  width: 30px;
  height: 30px;
  display: block;
  float: right;
  position: relative;
  margin: 10px;
}

.popup-wrap .popup .popup-btn::before,
.popup-wrap .popup .popup-btn::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(45deg);
  height: 1px;
  width: 100%;
  background-color: black;
}
.popup-wrap .popup .popup-btn::before{
    
  transform: translate(-50%, -50%) rotate(-45deg);
}

3.js

let popupBtn = document.querySelector(".popup-btn");
let popupEvent = document.querySelector('.event-btn');
let popupCookie = getCookie("event-popup");

function popupOpen(){
    let popup = document.querySelector('.popup-wrap');
    if(popup.classList.contains("is-on")){
        popup.classList.remove('is-on');
    }else{
        popup.classList.add('is-on');
    }
}

popupBtn.addEventListener("click",popupOpen);

popupEvent.addEventListener("click",function(){
    console.log('이벤트');
    // 쿠키 추가
    // 하루동안 유지되는 쿠키 생성.
    setCookie("event-popup",true,10);
})

// 문자로 저장되는구나. 쿠키, 로컬스토리지 둘다
// 코딩을하면서 데이터를 저장할때 문자열로 저장한다.
console.log(typeof getCookie("event-popup"))
// 하루동안 팝업 안보이기

// 쿠키값이 없으면 팝업이 작동하게 팝업이 뜨게
// 쿠키값이 없으면 undefined
if(popupCookie == undefined)
{
    popupOpen();
}

function getCookie(c_name)
{
   var i,x,y,ARRcookies=document.cookie.split(";");
   for (i=0;i<ARRcookies.length;i++)
   {
     x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
     y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
     x=x.replace(/^\s+|\s+$/g,"");
     if (x==c_name)
     {
       return unescape(y);
     }
   }
}

function setCookie(c_name,value,time){
    let date = new Date();
    date.setTime(date.getTime() + time * 1000);

    let str = c_name+"="+value+";expires="+date.toUTCString()+";path=/";
    let str2 = getCookieTime(str);
    console.log(str2);
    // 문자열로 데이터를 저장하는데
    // 값이 여러개일경우
    // 배열이라던지 객체를 사용
    // 여러가지의 값을 사용해야하기때문에 객체의 모양으로 문자열을 전달하고
    // 문자열을 받아서 객체로 변환하여 사용하자.
    console.log(getCookieTime(c_name+"="+value+";expires="+date.toUTCString()+";path=/"));
    document.cookie = c_name+"="+`{"value" : "${value}", "time" : "${str2}"}`+";expires="+date.toUTCString()+";path=/"
    let value2 = getCookie("event-popup");
    console.log(JSON.parse(value2));
}

function getCookieTime(cookie){
    // 쿠키 문자열을 받아서 배열로 변환
    let str = cookie.split(';');
    let str2 = str.find(function(i){
        let temp = i.trim();
        return temp.startsWith('expires=');
    })
    if(str2){
        console.log(str2);
        let str3 = str2.trim();
        console.log(str3);
        // 쿠키의 시간을 받아서 시간의 정보들을 다루는 
        // Date객체를 만들어줬다.
        return new Date(str3);
    }else{
        return null;
    }
}

// trim 메소드 : 문자열 양끝의 공백을 제거
let a = "    a b     ";
console.log(a);
console.log(a.trim());

// startsWith 메소드 : 해당 문자로 시작하는지 여부
// 매개변수로 시작하는 문자열 전달해주면 된다.

let b = "abcd";
console.log(b.startsWith("abc"))

// 시간의 차이를 구해서 값을 받아보자
// 밀리초를 받아서 시간이 얼마나 남은건지 확인하는 함수
// 시간계산을 할때 언제 시간이 만료되는지 알고있으면 되는거죠?
// 지금 시간의 정보를 가지고있는 Date객체를 만들어서
// 미래 시간의 밀리초와 지금 만든 Date객체의 밀리초를 빼면
// 차이값이 나오는데 그 차이값(밀리초)를 가지고 날짜와 시간과 분,초 이렇게 나타내주기만 하면 된다.
// times함수로 밀리초를 가지고 날짜 시간 분 초가 얼마나 남은건지.
let dateTemp = 1000;

// 비동기 함수 setTimeout이 함수는 매개변수로 전달한 시간이후에 실행되는 함수.
// setTimeout(() => {
//     // 1초뒤에 실행
// }, 1000);

// 비동기 함수
// 매초마다 동작하는 함수를 만들어보자
// 정한 시간마다 동작하는 함수
// 매개변수로 전달한 시간마다 동작한다.
// let date1 = new Date();
// date1.setTime(date1.getTime() + 100000);
// let time = JSON.parse(popupCookie).time;
// let date = new Date(time);
//console.log(date);
// setInterval 제거 방법
let setTime = setInterval(() => {
    let date2 = new Date();
    // // 값이 들어온것 객체가 아니고
    // let time = date1.getTime() - date2.getTime();
    // // 1초마다 실행
    // times(time);
    let timeTag = document.querySelector('.popup-time');
    if(popupCookie != undefined)
    {
        let time = JSON.parse(popupCookie).time;
        let date = new Date(time);
        console.log(date);
        console.log(date2);
        console.log(popupTime(date,date2));
        timeTag.innerHTML = times(popupTime(date, date2));
    }else{
        timeTag.innerHTML = "시간끝";
    }
}, 1000);

function popupTime(date1,date2) {
    return date1.getTime() - date2.getTime();
}

function times(time){
    // let sec = Math.floor(time / (24*60*60*1000));
    // let min = Math.floor(time / (60*60*1000));
    // console.log(min);
    let day = Math.floor(time / (24 * 60 * 60 * 1000));
    // 받아온 시간에서 날짜가 하루 단위가 있으면 나눠서 값을 넣어주고
    // 일단위를 빼고
    time %= (24 * 60 * 60 *1000);
    let hour = Math.floor(time / (60 * 60 * 1000));
    // 시간단위를 빼고
    time %= (60 * 60 * 1000);
    let min = Math.floor(time /(60 * 1000));
    // 분단위를 다빼고
    time %= (60 * 1000)
    // 남은 초
    let sec = Math.floor(time / 1000);
    console.log(day);
    console.log(hour);
    console.log(min);
    console.log(sec);
    if(time < 0)
    {
        // 지울 Interval 함수 매개변수로 전달하면된다.
        clearInterval(setTime);
        let timeTag = document.querySelector('.popup-time');
        timeTag.innerHTML = "";
    }
    return `${day}${hour}${min}${sec}`;
}

//
  • 변수 저장

    let popupBtn = document.querySelector(".popup-btn");
    let popupEvent = document.querySelector('.event-btn');
    let popupCookie = getCookie("event-popup");
    • 팝업 버튼은 누르면 팝업이 사라지는 버튼이다.
    • 팝업 이벤트는 팝업 창 내에서 쿠키를 저장시키는 용도이다.
    • 팝업 쿠키는 event-popup를 키로 가진 cookie의 value를 가져오는 역할을 한다.
  • 팝업창 온/오프를 결정하는 함수

    function popupOpen(){
        let popup = document.querySelector('.popup-wrap');
        if(popup.classList.contains("is-on")){
            popup.classList.remove('is-on');
        }else{
            popup.classList.add('is-on');
        }
    }
    • display:block이 있는 클래스가 있으면 제거,없으면 넣는 간단한 함수다.
  • 쿠키를 꺼내는 함수

    function getCookie(c_name)
    {
       var i,x,y,ARRcookies=document.cookie.split(";");
       for (i=0;i<ARRcookies.length;i++)
       {
         x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
         y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
         x=x.replace(/^\s+|\s+$/g,"");
         if (x==c_name)
         {
           return unescape(y);
         }
       }
    }
    
  • 쿠키를 설정하는 함수

    function setCookie(c_name,value,time){
        let date = new Date();
        date.setTime(date.getTime() + time * 1000);
    
        let str = c_name+"="+value+";expires="+date.toUTCString()+";path=/";
        let str2 = getCookieTime(str);
        console.log(str2);
        // 문자열로 데이터를 저장하는데
        // 값이 여러개일경우
        // 배열이라던지 객체를 사용
        // 여러가지의 값을 사용해야하기때문에 객체의 모양으로 문자열을 전달하고
        // 문자열을 받아서 객체로 변환하여 사용하자.
        console.log(getCookieTime(c_name+"="+value+";expires="+date.toUTCString()+";path=/"));
        document.cookie = c_name+"="+`{"value" : "${value}", "time" : "${str2}"}`+";expires="+date.toUTCString()+";path=/"
        let value2 = getCookie("event-popup");
        console.log(JSON.parse(value2));
    }
    • 쿠키에는 값과 시간(현재시간+1초*time)을 저장한다. 만료시간에도 역시 현재시간을 저장한다.
    • 그 후 value2에 할당한다.
  • 쿠키시간을 가져오는 함수

    function getCookieTime(cookie){
        // 쿠키 문자열을 받아서 배열로 변환
        let str = cookie.split(';');
        let str2 = str.find(function(i){
            let temp = i.trim();
            return temp.startsWith('expires=');
        })
        if(str2){
            console.log(str2);
            let str3 = str2.trim();
            console.log(str3);
            // 쿠키의 시간을 받아서 시간의 정보들을 다루는 
            // Date객체를 만들어줬다.
            return new Date(str3);
        }else{
            return null;
        }
    }
    • str에 ;을 기준으로 배열화한 쿠키를 할당한다.

    • trim()⇒글 양 끝의 간격을 없애준다.

    • expires= 로 시작하는 문자열을 find로 찾아 str2에 저장한다.

    • str3는 다음과 같다. 예) expires=Fri, 24 Mar 2023 07:37:40 GMT

      💡 여기서 중요한 건 Date()의 생성자로expires=Fri, 24 Mar 2023 07:37:40 GMT와 같은 문자형식이 들어가면 이에 해당하는 시간으로 변환 시켜 준다는 것이다!
  • 매 초 남은 쿠키시간을 갱신시켜주는 함수

    let setTime = setInterval(() => {
        let date2 = new Date();
        // // 값이 들어온것 객체가 아니고
        // let time = date1.getTime() - date2.getTime();
        // // 1초마다 실행
        // times(time);
        let timeTag = document.querySelector('.popup-time');
        if(popupCookie != undefined)
        {
            let time = JSON.parse(popupCookie).time;
            let date = new Date(time);
            console.log(date);
            console.log(date2);
            console.log(popupTime(date,date2));
            timeTag.innerHTML = times(popupTime(date, date2));
        }else{
            timeTag.innerHTML = "시간끝";
        }
    }, 1000);
    • date2로 현재시간을 가져온다.
    • timeTag는 남은시간을 띄워줄 태그이다.
    • popupCookie를 object로 변경해주고 만료일이 적혀있는 time을 가져온다.
    • 그 후 현재 시간과 남은시간을 빼준다.
  • 남은시간을 보기 좋게 format해주는 함수

    function times(time){
        // let sec = Math.floor(time / (24*60*60*1000));
        // let min = Math.floor(time / (60*60*1000));
        // console.log(min);
        let day = Math.floor(time / (24 * 60 * 60 * 1000));
        // 받아온 시간에서 날짜가 하루 단위가 있으면 나눠서 값을 넣어주고
        // 일단위를 빼고
        time %= (24 * 60 * 60 *1000);
        let hour = Math.floor(time / (60 * 60 * 1000));
        // 시간단위를 빼고
        time %= (60 * 60 * 1000);
        let min = Math.floor(time /(60 * 1000));
        // 분단위를 다빼고
        time %= (60 * 1000)
        // 남은 초
        let sec = Math.floor(time / 1000);
        console.log(day);
        console.log(hour);
        console.log(min);
        console.log(sec);
        if(time < 0)
        {
            // 지울 Interval 함수 매개변수로 전달하면된다.
            clearInterval(setTime);
            let timeTag = document.querySelector('.popup-time');
            timeTag.innerHTML = "";
        }
        return `${day}${hour}${min}${sec}`;
    }
    • ms단위로 온 시간에서 일,시간,분,초를 가져온다.
    • 만약 time<0 이라면. 즉, 만료시간이 지났다면 clearInterval을 이용해 setInterval을 제거한다.
    • 그 후 현재 남은 시간을 보기좋게 return한다.
  • 남은시간을 return하는 함수

    function popupTime(date1,date2) {
        return date1.getTime() - date2.getTime();
    }
    • 쿠키의 만료시간(date1)에서 현재시간(date2)을 빼주는 함수이다.

      두 시간의 차이(쿠키으)

느낀점

쿠키를 저장하고 불러온 다음 시간만을 빼내서 남은 쿠키의 시간을 계산한다.
단순히 현재시간과 만료시간을 비교해서 넣으면 되는줄 알고 우습게 봤다가 갖가지 오류에 멘탈이 터졌다.. 특히 json포맷 형식과 Date()의 파라미터형식을 찾는데 오랜시간이 걸렸다.
간단한 기능이라도 개발자의 실력에 따라 코드와 유지보수가 달라질 수 있음을 또 깨달았다..

profile
개발당시에 직면한 이슈를 정리하는 곳

1개의 댓글

comment-user-thumbnail
2023년 7월 19일

유익한 정보를 얻을 수 있어서 기쁩니다.

답글 달기