로컬스토리지
로컬스토리지 이해하기
로컬스토리지는 웹 브라우저에서 데이터를 영구적으로 저장할 수 있는 방법 중 하나입니다. 로컬스토리지에 저장된 데이터는 브라우저를 닫거나 컴퓨터를 재부팅해도 유지됩니다.
로컬스토리지는 개발자도구를 열어 확인할 수 있습니다. 개발자도구를 열고 Application
탭을 클릭하면 Storage
섹션에 Local Storage
를 확인할 수 있습니다.
로컬스토리지에 있는 값은 클릭해서 삭제할 수도 있는데요. 자사 서비스인 스터디인에 로그인 한 후 이 로컬스토리지에 값들을 비워보세요. 그러면 로그아웃이 되는 것을 확인할 수 있습니다.
1. 로컬스토리지란?
로컬스토리지는 브라우저에서 제공하는 클라이언트 측 저장소입니다. 주요 특징은 다음과 같습니다.
- 영구성: 데이터를 명시적으로 삭제하지 않는 한 유지됩니다.
- 키-값 쌍: 데이터를 키-값 쌍으로 저장합니다.
- 문자열 저장: 모든 데이터는 문자열 형식으로 저장됩니다.
2. 로컬스토리지 사용법
로컬스토리지의 주요 메서드는 다음과 같습니다.
setItem(key, value)
: 키-값 쌍 저장getItem(key)
: 키에 해당하는 값 호출removeItem(key)
: 키에 해당하는 값 삭제clear()
: 모든 데이터 삭제key(index)
: 인덱스에 해당하는 키 호출length
: 저장된 항목의 개수
3. 기본 사용 법
아래 파일을 html 파일로 만들어서 브라우저에서 실행해보세요.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>로컬스토리지 기본 사용</title>
</head>
<body>
<script>
// setItem: 데이터 저장
localStorage.setItem('name', 'licat');
localStorage.setItem('age', '10');
// getItem: 데이터 호출
console.log(localStorage.getItem('licat')); // licat
console.log(localStorage.getItem('age')); // 10
// removeItem: 데이터 삭제
localStorage.removeItem('name');
// clear: 모든 데이터 삭제
localStorage.clear();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>로컬스토리지 기본 사용</title>
</head>
<body>
<script>
// setItem: 데이터 저장
localStorage.setItem('name', 'licat');
localStorage.setItem('age', '10');
// getItem: 데이터 호출
console.log(localStorage.getItem('licat')); // licat
console.log(localStorage.getItem('age')); // 10
// removeItem: 데이터 삭제
localStorage.removeItem('name');
// clear: 모든 데이터 삭제
localStorage.clear();
</script>
</body>
</html>
이번에는 일반 텍스트가 아니라 객체를 저장해보겠습니다. 로컬스토리지는 문자열 형식으로만 데이터를 저장할 수 있으므로, 객체나 배열을 저장하려면 JSON.stringify를 사용하여 문자열로 변환해야 합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>로컬스토리지 객체와 배열 저장</title>
</head>
<body>
<script>
const memoArray = ['메모1', '메모2'];
localStorage.setItem('memos', JSON.stringify(memoArray));
const memoObject = { one: '메모1', two: '메모2' };
localStorage.setItem('memoObject', JSON.stringify(memoObject));
console.log(JSON.parse(localStorage.getItem('memos'))); // ['메모1', '메모2']
console.log(JSON.parse(localStorage.getItem('memoObject'))); // { one: '메모1', two: '메모2' }
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>로컬스토리지 객체와 배열 저장</title>
</head>
<body>
<script>
const memoArray = ['메모1', '메모2'];
localStorage.setItem('memos', JSON.stringify(memoArray));
const memoObject = { one: '메모1', two: '메모2' };
localStorage.setItem('memoObject', JSON.stringify(memoObject));
console.log(JSON.parse(localStorage.getItem('memos'))); // ['메모1', '메모2']
console.log(JSON.parse(localStorage.getItem('memoObject'))); // { one: '메모1', two: '메모2' }
</script>
</body>
</html>
3. 메모장 예제
로컬스토리지를 사용하여 간단한 메모장 애플리케이션을 만들어보겠습니다. 사용자가 입력한 메모를 저장하고, 저장된 메모를 화면에 표시하며, 삭제할 수 있는 기능을 구현합니다. 아래 소스코드를 활용하여 메모장 예제를 완성해보세요.
<!DOCTYPE html>
<html lang="ko">
<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" />
<style>
main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
input {
display: block;
width: 300px;
height: 30px;
margin-bottom: 10px;
}
textarea {
display: block;
width: 300px;
height: 300px;
margin-bottom: 10px;
}
button {
display: block;
width: 306px;
height: 30px;
}
</style>
</head>
<body>
<main>
<section>
<input type="text" name="" id="title" />
<textarea name="" id="content" cols="30" rows="10"></textarea>
<button onclick="saveNote()">메모</button>
</section>
<section id="display"></section>
</main>
<script>
let allMemo = JSON.parse(localStorage.getItem('allMemo'));
allMemo = allMemo ?? [];
render();
function saveNote() {
const title = document.getElementById('title').value;
const content = document.getElementById('content').value;
allMemo.push({ title, content, len: allMemo.length });
localStorage.setItem('allMemo', JSON.stringify(allMemo));
render();
}
function render() {
const display = document.getElementById('display');
display.innerHTML = '';
// // 최신 게시물이 위로 올라오도록
// for (let i = allMemo.length; i > 0 ; i--) {
// // 아래와 유사 코드
// }
for (const item of allMemo) {
const saveTitle = document.createElement('h2');
const saveContent = document.createElement('p');
const saveId = document.createElement('p');
const deleteMemoBtn = document.createElement('button');
saveTitle.textContent = item.title;
saveContent.textContent = item.content;
saveId.textContent = item.len + 1;
deleteMemoBtn.textContent = '삭제';
deleteMemoBtn.setAttribute('id', item.len);
deleteMemoBtn.setAttribute('onclick', 'remove()');
display.appendChild(saveId);
display.appendChild(saveTitle);
display.appendChild(saveContent);
display.appendChild(deleteMemoBtn);
}
}
function remove() {
// console.log(event.srcElement.id);
// console.log(allMemo);
const idx = allMemo.find((item) => item.len == event.srcElement.id);
if (idx) {
allMemo.splice(
allMemo.findIndex((item) => item.len == idx.len),
1,
);
}
localStorage.setItem('allMemo', JSON.stringify(allMemo));
render();
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="ko">
<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" />
<style>
main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
input {
display: block;
width: 300px;
height: 30px;
margin-bottom: 10px;
}
textarea {
display: block;
width: 300px;
height: 300px;
margin-bottom: 10px;
}
button {
display: block;
width: 306px;
height: 30px;
}
</style>
</head>
<body>
<main>
<section>
<input type="text" name="" id="title" />
<textarea name="" id="content" cols="30" rows="10"></textarea>
<button onclick="saveNote()">메모</button>
</section>
<section id="display"></section>
</main>
<script>
let allMemo = JSON.parse(localStorage.getItem('allMemo'));
allMemo = allMemo ?? [];
render();
function saveNote() {
const title = document.getElementById('title').value;
const content = document.getElementById('content').value;
allMemo.push({ title, content, len: allMemo.length });
localStorage.setItem('allMemo', JSON.stringify(allMemo));
render();
}
function render() {
const display = document.getElementById('display');
display.innerHTML = '';
// // 최신 게시물이 위로 올라오도록
// for (let i = allMemo.length; i > 0 ; i--) {
// // 아래와 유사 코드
// }
for (const item of allMemo) {
const saveTitle = document.createElement('h2');
const saveContent = document.createElement('p');
const saveId = document.createElement('p');
const deleteMemoBtn = document.createElement('button');
saveTitle.textContent = item.title;
saveContent.textContent = item.content;
saveId.textContent = item.len + 1;
deleteMemoBtn.textContent = '삭제';
deleteMemoBtn.setAttribute('id', item.len);
deleteMemoBtn.setAttribute('onclick', 'remove()');
display.appendChild(saveId);
display.appendChild(saveTitle);
display.appendChild(saveContent);
display.appendChild(deleteMemoBtn);
}
}
function remove() {
// console.log(event.srcElement.id);
// console.log(allMemo);
const idx = allMemo.find((item) => item.len == event.srcElement.id);
if (idx) {
allMemo.splice(
allMemo.findIndex((item) => item.len == idx.len),
1,
);
}
localStorage.setItem('allMemo', JSON.stringify(allMemo));
render();
}
</script>
</body>
</html>