[JS] Level3 12-14강

ByeolGyu·2024년 6월 24일

JavaScript

목록 보기
9/17

✔ DOM & load 이벤트 (12강)

DOM (Document Object Model)

JavaScript가 HTML을 조작하는 법

  • JavaScript는 HTML 조작에 특화된 언어

  • JS는 HTML과 다른 언어이기 때문에 <p></p>.innerHTML = '안녕'은 불가

  • JavaScript가 HTML을 조작하기 위해서 HTML을 JavaScript가 해석할 수 있는 문법으로 반환
    즉 Array 혹은 Object 자료형에 담음

  • 예) 브라우저는 <div style="color : red">안녕하세요</div> 이 HTML을 발견하면
    → Object 자료로 바꿔서 보관
    즉, 아래와 같이 object 자료에 정리

      var document = {
        div1 : {
          style : {color : 'red'}
          innerHTML : '안녕하세요'
        }
      }

자바스크립트가 HTML에 대한 정보들 (id, class, name, style, innerHTML 등)을 object 자료로 정리한r것을 DOM 이라고 부름

DOM 생성

  • 브라우저는 HTML 문서를 위에서 부터 읽으면서 DOM을 생성
  • 읽을 때 마다 HTML을 발견하면 DOM에 추가
  • 자바스크립트는 DOM이 생성된 경우에만 HTML을 변경할 수 있음
<script>
  document.getElementById('test').innerHTML = '안녕' 
  // 아직 <p id="test">를 읽기 전이라 p태그에 대한 DOM이 아직 생성되지 않아 변경 불가!
</script>

<p id="test">임시글자</p>

JS 실행 미루기

  • HTML을 전부 읽고 실행하도록 코드를 짤 수 있음
  • "HTML을 다 읽어들였는지"를 알려주는 이벤트리스너
$(document).ready(function(){ 실행할 코드 });
// 또는
document.addEventListener('DOMContentLoaded', function() { 실행할 코드 }) ;
  • 이 이벤트 리스너를 사용하면
<script>
  document.addEventListener('DOMContentLoaded', function() { 
    document.getElementById('test').innerHTML = '안녕' // 잘 작동
  })
</script>

<p id="test">임시글자</p>

load 이벤트리스너

  • load라는 이벤트 리스너를 사용하면
    DOM 생성뿐만 아니라 이미지, css, js파일이 로드가 됐는지도 체크가능

셀렉터로찾은이미지.addEventListener('load', function(){})

  • 이미지 등이 로드되면 load라는 이벤트가 발생
셀렉터로찾은이미지.addEventListener('load', function(){
  //이미지 로드되면 실행할 코드 
})
  • 외부 자바스크립트 파일에 위와 같이 적어놓으면
    그 js 파일보다 이미지가 더 먼저 로드되는 경우도 있어이벤트 발생체크를 못할 수도 있음

window 사용

  • document에 포함된 이미지, CSS파일 등 모든것이 로드가 되었는지 체크
  • ready와의 차이점
    : ready는 DOM 생성만 체크하는 함수
    window를 사용하면 모든 파일과 로드상태 체크 가능
  • but) 이렇게 코드를 짜면 느려짐
$(window).on('load', function(){
  //document 안의 이미지, js 파일 포함 전부 로드가 되었을 경우 실행할 코드 
});

window.addEventListener('load', function(){
  //document 안의 이미지, js 파일 포함 전부 로드가 되었을 경우 실행할 코드
})

✔ localStorage (13강)

브라우저 저장 공간

Local Storage

  • key : value 형태로 문자, 숫자 데이터 저장가능
  • 문자, 숫자만 key : value 형태로 저장가능하고 5MB까지만 저장가능
  • 범용적 사용 가능
  • 브라우저 재접속해도 데이터 영구적으로 남아있음
  • 유저가 브라우저 청소하지 않는 이상 반영구적으로 데이터저장이 가능

Session Storage

  • key : value 형태로 문자, 숫자 데이터 저장가능
  • 문자, 숫자만 key : value 형태로 저장가능하고 5MB까지만 저장가능
  • 브라우저 재접속하면 데이터 날아감

Indexed DB

  • 크고 많은 구조화된 데이터를 DB처럼 저장가능
  • 문법이 복잡

Cookies

  • 유저 로그인정보 저장공간

Cache Storage

  • html css js img 파일 저장해두는 공간

localStorage 사용법

저장 / 꺼내기 / 삭제

  • 문자나 숫자만 저장 가능
  • 수정은 없어서 자료를 꺼내서 수정하고 다시 저장
  • ( sessionStorage.으로 바꾸면 Session Storage에 저장가능)
localStorage.setItem('이름', 'kim') //자료저장
localStorage.getItem('이름') //자료꺼내기
localStorage.removeItem('이름') //자료삭제

로컬스토리지에 array/object 저장

  • array/object를 로컬스토리지에 저장하면 강제로 문자로 바꿔서 저장됨
    but) 자료가 깨질 수 있음
    localStorage.setItem('number', '1, 2, 3');

자료 깨짐 해결

→ array/object를 JSON으로 바꾸면 문자취급을 받기 때문에 안전하게 로컬스토리지에 저장가능

var arr = [1,2,3];
var newArr = JSON.stringify(arr); // JSON으로 변환

localStorage.setItem('num', newArr)
  • JSON.stringify() 안에 array/object 집어넣으면 JSON으로 바꿔줌
    → 문자취급

로컬스토리지에 array/object 꺼내기

  • JSON으로 저장했으니 꺼내도 JSON
    → 꺼낸걸 다시 array/object로 바꾸고 싶으면 JSON.parse() 안에 넣어 변환
//꺼내서 쓸 때
        var no = localStorage.getItem('num');
        console.log(no); // "[1, 2, 3]"
        no = JSON.parse(no); //JSON을 array나 object로 변환
        console.log(no); // [1, 2, 3]
        console.log(no[1]); // 2

즉,

  • array/object -> JSON으로 변환하고 싶으면 JSON.stringify()
  • JSON -> array/object 으로 변환하고 싶으면 JSON.parse()

로컬스토리지에서 데이터 수정

  1. 자료 꺼내고
  2. 꺼낸거 수정
  3. 다시 넣기
// 로컬 스토리지 데이터 수정
        // 1. 자료 꺼내고 2. 꺼낸거 수정 3. 다시 넣기
        var newNo = [1, 2, 3, 4];
        no = JSON.stringify(newNo);
        localStorage.setItem('num', newNo);

✔ localStorage & 장바구니 기능(14강)

localStorage로 장바구니 기능

1번 풀이

        // 카드 생성
        function createCard(item, i){
            return `<div class="col-sm-4">
                        <img src="https://via.placeholder.com/600" class="w-100">
                       <h5>${item.title}</h5>
                        <p>가격 : ${item.price}</p>
                        <button class="buy" data-id="${i}">구매</button>
                    </div>`;
        }
        // <button class="buy" data-id="${i}">구매</button>는 javascript로 동적으로 생성됨
         // ->  이벤트 위임을 사용한 구매 버튼 클릭 이벤트
         $(document).on('click', '.buy', function(e){
            var productId = e.target.dataset.id;
            var cartProduct = allProducts[productId];

            if(localStorage.getItem('cart') == null){
                let cart = [cartProduct.title];
                var cartList = JSON.stringify(cart);
                localStorage.setItem('cart', cartList);
            } else {
                var cartList = JSON.parse(localStorage.getItem('cart'));
                cartList.push(cartProduct.title);
                localStorage.setItem('cart', JSON.stringify(cartList));
            }
        }); 

2번 풀이

  • siblings로 형제 요소 찾기
function createCard(item, i){
            return `<div class="col-sm-4">
                        <img src="https://via.placeholder.com/600" class="w-100">
                       <h5>${item.title}</h5>
                        <p>가격 : ${item.price}</p>
                        <button class="buy">구매</button>
                    </div>`;
        }
        $(document).on('click', '.buy', function(e){
            var title = $(e.target).siblings('h5').text(); // 타겟의 형제 중 h5의 텍스트
            var cart = JSON.parse(localStorage.getItem('cart')) || []; // 없으면 빈 배열로 초기화
            var itemIdx = cart.findIndex(item => item.title == title);
            if (itemIdx == -1){
                cart.push({title : title, cnt : 1});
            } else {
                cart[itemIdx].cnt++;
            }
            localStorage.setItem('cart', JSON.stringify(cart));
        });

장바구니 페이지

splice 메서드

  • 배열의 요소를 추가, 제거 또는 교체할 수 있는

  • 여러 개의

  • 첫 번째 인자 : 배열에서 요소를 추가하거나 제거할 위치 지정

  • 두 번째 인자 : 배열에서 제거할 요소의 수, 만약 0이면 요소는 제거되지 않고 추가만 됨

  • 세 번째 부터 그 이후 인자 : 배열에 추가 할 요소 (선택사항)

  • cartItems.splice(removeItem, 1);
    :배열에서 제거 할 요소의 인덱스를 1대 제거

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
    <div>장바구니 페이지</div>
    <div id="cartItems">
        <!-- 장바구니 상품 목록 -->
    </div>

    <script>
        $(document).ready(function(){
            var cartItems = JSON.parse(localStorage.getItem('cart')) || [];

            function displayCartItems(){
                var cartContainer = $('#cartItems');
                cartContainer.empty(); // 기존 내용 초기화

                if(cartItems.length > 0){
                    cartItems.forEach((item, idx) => {
                          var itemHTML = `
                            <div class="cart-item">
                                <p>${item.title}</p>
                                <p>${item.cnt} 개</p>
                                <button class="remove-item" data-idx="${idx}">삭제</button>
                            </div>`;
                            cartContainer.append(itemHTML);
                    });
                    $('.remove-item').click(()=>{
                        var removeItem = $(this).data('idx');
                        cartItems.splice(removeItem, 1);
                        localStorage.setItem('cart', JSON.stringify(cartItems));
                        displayCartItems();
                    });    
                } else {
                   cartContainer.html(`<p>장바구니가 비어있습니다.</p>`)
                }
            }
            displayCartItems();
        });
    </script>
    
</body>
</html>
profile
ByeolGyu

0개의 댓글