[miniProjects] 33_Notes App

๋ณด๋ฆฌยท2023๋…„ 6์›” 22์ผ
0

miniProjects

๋ชฉ๋ก ๋ณด๊ธฐ
33/47

33_Notes App

๐Ÿ’ป์ฃผ์ œ : ๋งˆํฌ๋‹ค์šด ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ๋ฉ”๋ชจ์žฅ

  • ๋ฉ”๋ชจ ์ถ”๊ฐ€
  • ๋ฉ”๋ชจ ์ €์žฅ(ํŽธ์ง‘)
  • ๋ฉ”๋ชจ ์‚ญ์ œ
  • ๋ฉ”๋ชจ ๋ฐ์ดํ„ฐ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅํ•˜๊ธฐ

โœจ๋งˆํฌ๋‹ค์šด cdn

<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/5.1.0/marked.min.js" integrity="sha512-j5KAPeir0rGl+OSddiUeUtUlG+GK7acI/kNQqrpjSSB1IlDUbj3VnQOyoW3GWpPj7i8CSfb0T+Q4IRHxAPRxCA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

โœจJS

const addBtn = document.getElementById('add')

addBtn.addEventListener('click', () => addNewNote())

function addNewNote(text = '') {
    const note = document.createElement('div')
    note.classList.add('note')

    note.innerHTML = `
    <div class="tools">
        <button class="edit"><i class="fas fa-edit"></i></button>
        <button class="delete"><i class="fas fa-trash-alt"></i></button>
    </div>

    <div class="main ${text ? "" : "hidden"}"></div>
    <textarea class="${text ? "hidden" : ""}"></textarea>
    `

    const editBtn = note.querySelector('.edit')
    const deleteBtn = note.querySelector('.delete')
    const main = note.querySelector('.main')
    const textArea = note.querySelector('textarea')

    textArea.value = text
    main.innerHTML = marked(text)

    deleteBtn.addEventListener('click', () => {
        note.remove()

        updateLS()
    })

    editBtn.addEventListener('click', () => {
        main.classList.toggle('hidden')
        textArea.classList.toggle('hidden')
    })

    textArea.addEventListener('input', (e) => {
        const { value } = e.target

        main.innerHTML = marked(value)

        updateLS()
    })

    document.body.appendChild(note)
}
  • 'add' ๋ฒ„ํŠผ์˜ 'click' ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด addNewNote ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋นˆ ํ…์ŠคํŠธ๋กœ ํ˜ธ์ถœ๋œ๋‹ค.

  • addNewNote ํ•จ์ˆ˜๋Š” ๋…ธํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  HTML ์š”์†Œ์— ์ถ”๊ฐ€ํ•œ๋‹ค. ํ…์ŠคํŠธ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์•„ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋นˆ ํ…์ŠคํŠธ๋กœ ์„ค์ •ํ•œ๋‹ค.

  • note ์š”์†Œ ๋‚ด๋ถ€์—๋Š” ํŽธ์ง‘ ๋ฒ„ํŠผ(edit)๊ณผ ์‚ญ์ œ ๋ฒ„ํŠผ(delete)์ด ์žˆ๋‹ค. ํ…์ŠคํŠธ ์˜์—ญ(textarea)๊ณผ ํ…์ŠคํŠธ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฉ”์ธ ์˜์—ญ(main)๋„ ์žˆ๋‹ค.

    text๊ฐ€ ์žˆ์œผ๋ฉด ๊ทธ๋ƒฅ mainํด๋ž˜์Šค, ์—†์œผ๋ฉด main hidden ํด๋ž˜์Šค๋กœ ๋ณ€๊ฒฝ

  • deleteBtn์€ ์‚ญ์ œ ๋ฒ„ํŠผ์ด๋‹ค.
    ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํ•ด๋‹น ๋…ธํŠธ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  updateLS ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ localStorage๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

  • editBtn์€ ํŽธ์ง‘ ๋ฒ„ํŠผ์ด๋‹ค.
    ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ฉ”์ธ ์˜์—ญ๊ณผ ํ…์ŠคํŠธ ์˜์—ญ์˜ ๊ฐ€์‹œ์„ฑ์„ ํ† ๊ธ€ํ•œ๋‹ค.

  • textArea๋Š” ํ…์ŠคํŠธ ์˜์—ญ์ด๋‹ค.
    text ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋œ ํ…์ŠคํŠธ๋ฅผ ์„ค์ •ํ•œ๋‹ค.

  • textArea์˜ ์ž…๋ ฅ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ๋ฆฌ์Šค๋„ˆ.
    (value๋Š” target ์š”์†Œ์˜ ์†์„ฑ ์ค‘ ํ•˜๋‚˜๋กœ, ์ผ๋ฐ˜์ ์œผ๋กœ input ์š”์†Œ๋‚˜ textarea ์š”์†Œ์™€ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๊ฐ’์„ ๋‚˜ํƒ€๋‚ด๋Š” ์†์„ฑ)

    ํ…์ŠคํŠธ ์˜์—ญ์ด ๋ณ€๊ฒฝ๋˜๋ฉด ์ž…๋ ฅ๋œ ๊ฐ’์„ ๊ฐ€์ ธ์™€ main ์˜์—ญ์— ํ‘œ์‹œํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  updateLS ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ localStorage๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

๐Ÿ’พ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ

const notes = JSON.parse(localStorage.getItem('notes'))

if(notes) {
    notes.forEach(note => addNewNote(note))
}

function updateLS() {
    const notesText = document.querySelectorAll('textarea')

    const notes = []

    notesText.forEach(note => notes.push(note.value))

    localStorage.setItem('notes', JSON.stringify(notes))
}
  • localStorage์—์„œ 'notes'๋ผ๋Š” ํ‚ค๋กœ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ notes ๋ณ€์ˆ˜์— ํ• ๋‹นํ•œ๋‹ค. ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋Š” JSON ํ˜•์‹์œผ๋กœ ์ €์žฅ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ JSON.parse๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์‹ฑํ•œ๋‹ค.

localStorage๋Š” ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” ์˜๊ตฌ์ ์ธ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ localStorage์— ์ €์žฅํ•  ๋•Œ๋Š” ํ‚ค-๊ฐ’ ์Œ์œผ๋กœ ์ €์žฅํ•˜๋ฉฐ, ๊ฐ’์€ ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ์ €์žฅ๋œ๋‹ค.

JSON.parse()๋Š” JSON ํ˜•์‹์˜ ๋ฌธ์ž์—ด์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋‹ค.

์œ„์˜ ์ฝ”๋“œ์—์„œ localStorage.getItem('notes')๋Š” localStorage์—์„œ 'notes'๋ผ๋Š” ํ‚ค๋กœ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค. ์ด ๋ฐ์ดํ„ฐ๋Š” ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ์ €์žฅ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, JSON.parse() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ๋ฌธ์ž์—ด์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ notes ๋ณ€์ˆ˜์—๋Š” 'notes' ํ‚ค๋กœ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๊ฐ€์ ธ์˜จ ๊ฐ’์ด ํ• ๋‹น๋œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ด์ „์— ์ €์žฅ๋œ ๋…ธํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์›ํ•˜์—ฌ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

  • notes ๋ฐฐ์—ด์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ, ๊ฐ ๋…ธํŠธ์— ๋Œ€ํ•ด addNewNote ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋…ธํŠธ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

    notes ๋ฐฐ์—ด์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ๋Š” localStorage์—์„œ 'notes'๋ผ๋Š” ํ‚ค๋กœ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„, ํ•ด๋‹น ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
    ๋งŒ์•ฝ ์ด์ „์— ๋…ธํŠธ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ localStorage์— 'notes'๋ผ๋Š” ํ‚ค๋กœ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, notes ๋ฐฐ์—ด์— ํ•ด๋‹น ๋ฐ์ดํ„ฐ๊ฐ€ ํ• ๋‹น๋œ๋‹ค. ์ด๋•Œ notes ๋ฐฐ์—ด์€ ์ด์ „์— ์ž‘์„ฑํ•œ ๋…ธํŠธ๋“ค์˜ ํ…์ŠคํŠธ๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค.

  • updateLS ํ•จ์ˆ˜๋Š” textarea ์š”์†Œ๋“ค์„ ๋ชจ๋‘ ์„ ํƒํ•˜์—ฌ ํ•ด๋‹น ๊ฐ’๋“ค์„ ๋ฐฐ์—ด์— ์ €์žฅํ•œ๋‹ค.
    ์ด ๋ฐฐ์—ด์„ JSON ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ 'notes'๋ผ๋Š” ํ‚ค๋กœ localStorage์— ์ €์žฅํ•œ๋‹ค.


๐Ÿ‘๐Ÿป์œ„์˜ ์ด๋ฏธ์ง€์ฒ˜๋Ÿผ ๋…ธํŠธ ์ž‘์„ฑ ์‹œ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ๋ฉ”๋ชจ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋“ค์ด ๋ฐฐ์—ด๋กœ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Œ.

profile
์ •์‹ ์ฐจ๋ ค ์ด ๊ฐ๋ฐ•ํ•œ ์„ธ์ƒ์†์—์„œ

0๊ฐœ์˜ ๋Œ“๊ธ€