본문 바로가기
작은 모듈(IT구슬)

브라우저에서 새로 고침 할 때 현재값 유지하기

by IT여행자 2023. 9. 23.
728x90

안녕하세요 IT여행자입니다.

 

웹 특성 중 하나가 브라우저를 새로 고침 하면  현재 값이 유지되지 않는다는 것입니다. 따라서 현재 값을 유지하거나 새로고침 현상 없이 현재 값을 다른 값으로 변경하기 위한 다양한 방법들이 존재합니다. 현재 값을 유지한다는 것이 웹 프로그램이 아닌 일반 컴퓨터 프로그램들에게서는 별거 아닌 문제이기는 합니다. 그냥 변수에 담아 필요한 시점이나 장소에 그냥 대입해 주면 당연히 화면에 출력되기 때문입니다. 그러나 서두에 말한 것처럼 웹은 정확히는 http 프로토콜 특성상 기본적으로 상태값 또는 현재값을 유지해 주는 기능이 없습니다.

 

대부분의 FRONT-END 프레임워크에서는 이런 상태값을 유지해 주는 기능을 지원하여 약간의 노력만 하면 대부분 해결할 수 있을 것입니다. 본 지면에서는 외부의 라이브러리나 프레임워크를 사용하지 않고도 상태값(현재값)을 유지하거나 수정된 값을 바로바로 웹 화면에 출력하는 기능을 살펴보려고 합니다.

 

그 기능은 바로 localStorage 또는 sessionStorage를 사용하는 방법인데, 고도화된 라이브러리처럼 고급기능까지는 내용이 너무 길어짐으로 웹 프로그램을 개발할 때 영감을 떠올릴 수 있는 정도까지만 살펴보려고 합니다. 

 

 

두 번째 예를 실행하면 위 그림과 같이 성명과 성별상태, 취미 선택 상태가 페이지를 새로고침하거나 다른 곳으로 이동했다 다시 되돌아오는 경우 마지막 상태값이 변경되지 않고 재 설정됩니다.

 

 

[첫 번째 예]

 

1. 페이지가 로딩되면 sessionStorage에서 cnt(카운트) 값이 있는지 체크한 후 값이 존재하면 해당 요소의 값을 화면에 적용시킵니다.

 

<label class="count"></label>

...

const count = document.querySelector('.count')

let cnt = 0
if(sessionStorage.getItem("cnt") != null){
     cnt = Number(sessionStorage.getItem("cnt"))
}

count.textContent = cnt

 

2. up 버튼과 down 버튼을 추가하고 해당 버튼이 클릭되면 cnt변수를 증감시킨 후 <label/> 태그에 값을 표시합니다. 증감된 값은 다시 sessionStorage에 저장해 둡니다.

 

<button class="up" type="button">UP</button>
<button class="down" type="button">DOWN</button>

...

const up = document.querySelector('.up')
const down = document.querySelector('.down')

up.addEventListener('click', ()=>{
    cnt++;
    count.textContent = cnt
    sessionStorage.setItem("cnt", cnt)
})

down.addEventListener('click', ()=>{
    cnt--;
    count.textContent = cnt
    sessionStorage.setItem("cnt", cnt)
})

 

전체 코드는 아래와 같습니다. 아래의 코드에서는 즉시 실행함수를 사용하였고 label태그와 두 개의 버튼의 class값을 인수값으로 전달하였고 이를 배열의 첨자를 사용하여 객체를 생성하는 데 사용하였습니다.

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sessionStorage</title>
</head>
<body>
    <div>
        <label class="count"></label>
    </div>
    <button class="up" type="button">UP</button>
    <button class="down" type="button">DOWN</button>
    <script>
        (
            (ele)=>{
                let cnt = 0
                const count = document.querySelector(ele[0])
                const up = document.querySelector(ele[1])
                const down = document.querySelector(ele[2])

                if(sessionStorage.getItem("cnt") != null){
                    cnt = Number(sessionStorage.getItem("cnt"))
                }

                count.textContent = cnt

                up.addEventListener('click', ()=>{
                    cnt++;
                    count.textContent = cnt
                    sessionStorage.setItem("cnt", cnt)
                })

                down.addEventListener('click', ()=>{
                    cnt--;
                    count.textContent = cnt
                    sessionStorage.setItem("cnt", cnt)
                })

            }

        )(['.count', '.up', '.down'])
    </script>
</body>
</html>

 

현재 상태값을 유지하는 것 중 가장 복잡한 것은 라디오 버튼이나 체크박스 유형일 것입니다. 두 번째 예제는 <form/> 태그 안에 있는 요소들을 sessionStorage에 저장해 보도록 하겠습니다.

 

[두 번째 예제]

<form/> 안에 있는 정보를 실시간으로 저장하여 현재 상태를 유지하거나 다른 페이지동 이동했다가 다시 현재 페이지로 되돌아왔을 때도 입력했던 내용을 그대로 표시해 보도록 하겠습니다.

 

1. 페이지가 로딩되거나 새로고침되면 setForm() 함수를 호출하여 sessionStorage에 있는 정보를 읽어 <form/> 태그에 적용합니다.

 

let frm = document.frm
const setForm = ()=>{
    let temp = sessionStorage.getItem("frm")
    let data = JSON.parse(temp)
    frm.name.value = data.name

    /* 라디오 버튼 상태 복원 */
    Array.from(frm.gender).forEach( (g, index)=>{
        g.checked = data.gender[index]
    })
    /* 체크 박스 상태 복원 */
    Array.from(frm.hobby).forEach( (h, index)=>{
        h.checked = data.hobby[index]
    })
}

if(sessionStorage.getItem("frm") != null){
    setForm();
}

 

위 코드에서 사용된 Array.from() 함수는 배열 형태를 갖고 있는 요소들을 실제로 배열로 변환해 주는 함수입니다. 배열로 변환된 내용을 forEach() 함수를 사용하여 하나씩 가져와 해당 요소의 checked 상태를 sesstionStorage에 저장된 값으로 하나씩  다시 설정하는 부분이 g.checked = data.gender[index] 또는 h.checked = data.hobby [index]입니다.

 

2. 브라우저에서 새로고침을 하기 전 이거나 다른 페이지로 이동하기 전 이벤트를 처리하는 코드를 추가해 줍니다.

 

/* 페이지가 다른 곳으로 이동될 때 */
window.addEventListener('beforeunload', statusCheck);

 

3. <form/> 안에서 상태가 바뀌는 경우 이벤트를 처리합니다.

 

/* form안에서 변화가 일어나면 */
frm.addEventListener('change', statusCheck);

 

4. 브라우저 상태값이 바뀌거나 <form/> 안에서 상태가 바뀌거나 호출되는 함수가 statusCheck() 함수입니다.

 

function statusCheck(){
    let name = frm.name.value
    let gender = Array.from(frm.gender).map(g=>g.checked)
    let hobby = Array.from(frm.hobby).map(h=>h.checked)

    let data = {
        name : name,
        gender : gender,
        hobby : hobby
    }
    let json = JSON.stringify(data);
    sessionStorage.setItem("frm", json)
}

 

Array.from() 함수를 사용하여 라디오 버튼이나 체크박수의 요소들을 배열로 가져와 해당 요소들의 체크 상태값만을 배열로 처리하는 부분이 Array.from(frm.gender). map(g=> g.checked)와 Array.from(frm.hobby). map(h=> h.checked)입니다.

처리된 내용을 리터널 타입으로 저장한 변수가 data이며 sessionStorage에는 문자열로 이루어진 자료들만 저장할 수 있으므로 JSON.stringify(data)를 사용하여 문자열로 변환한 후 sessionStorage에 저장하고 있습니다.

 

전체 코드는 아래와 같습니다.

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sessionStorage</title>
</head>
<body>
    <form name="frm" class="frm">
        <label>성명</label>
        <input type="text" name="name"><br/>
        <label>성별</label>
        <label><input type="radio" name="gender" value="m">남자</label>
        <label><input type="radio" name="gender" value="f">여자</label><br/>
        <label>취미</label>
        <label><input type="checkbox" name="hobby" value="축구">축구</label>
        <label><input type="checkbox" name="hobby" value="등산">등산</label>
        <label><input type="checkbox" name="hobby" value="독서">독서</label>
        <label><input type="checkbox" name="hobby" value="여행">여행</label><br/>
    </form>

    <script>
        let frm = document.frm;

        const setForm = ()=>{
            let temp = sessionStorage.getItem("frm");
            let data = JSON.parse(temp);
            frm.name.value = data.name;

            /* 라디오 버튼 상태 복원 */
            Array.from(frm.gender).forEach( (g, index)=>{
                g.checked = data.gender[index]
            })
            /* 체크 박스 상태 복원 */
            Array.from(frm.hobby).forEach( (h, index)=>{
                h.checked = data.hobby[index]
            })
        }

        if(sessionStorage.getItem("frm") != null){
            setForm();
        }

        /* 페이지가 다른 곳으로 이동될때 */
        window.addEventListener('beforeunload', statusCheck);

        /* form안에서 변화가 일어나면 */
        frm.addEventListener('change', statusCheck);
        function statusCheck(){
            let name = frm.name.value
            let gender = Array.from(frm.gender).map(g=>g.checked)
            let hobby = Array.from(frm.hobby).map(h=>h.checked)

            let data = {
                name : name,
                gender : gender,
                hobby : hobby
            }
            let json = JSON.stringify(data);
            sessionStorage.setItem("frm", json)
        }
    </script>
</body>
</html>

 

다른 라이브러리나 프레임워크 없이 현재의 상태값을 저장하고 유지하는 코드를 작성해 보았습니다. 이런 상태값을 관리해 주는 라이브러리나 프레임워크만큼 간단하지는 않겠지만 다른 코드들을 작성할 때 영감을 받을 수는 있을 것이라 생각됩니다. 

 

감사합니다.