[JavaScript 15] 이벤트 활용

김헤일리·2022년 12월 2일
0

JavaScript

목록 보기
16/20

HTML에 입력 양식(Form)과 JavaScript

  • 문서 객체 모델을 통해 JavaScript는 HTML과 연관되어 영향을 줄 수 있다.

    • JavaScript는 HTML에서 일어나는 이벤트를 감지하고 변경할 수 있다.
  • JavaScript의 기본 문법인 조건문, 반복문, 함수 등을 통해서 다양한 이벤트를 활용할 수 있다.

    • 다양한 이벤트를 활용하면 동적인 웹사이트를 제작할 수 있다.

1. 이벤트 모델

  • 이벤트를 연결하는 방법을 이벤트 모델이라고 한다.
  • 모든 이벤트 모델의 이벤트 리스너는 첫 번째 매새변수로 이벤트 객체 (event object)를 받는다.
    • 이벤트 객체엔 이벤트에 관련된 정보가 들어있다.
    • 이벤트 객체의 종류는 브라우저 개발자도구에서 확인할 수 있다.

✏️ 표준 이벤트 모델

  • 이벤트 연결 시 addEventListenenr() 라는 메소드를 활용할 수 있고, 현재 해당 방식이 표준으로 적용되고 있기 때문에 "표준 이벤트 모델" 이라고도 부른다.
    • 표준으로 사용하는 이유는 자바스크립트로 기능을 구현한다고 했을 때, 이벤트 리스너를 여러개 연결시킬 수 있기 때문이다.
    • 예시:
  document.body.addEventListener('keyup', () => {} 
  // HTML 바디 부분에서 'keyup'이라는 이벤트를 감지한다. 
  // () 인자를 두개 넣는데, 그 중 첫번째 인자가 감지하고자 하는 이벤트 (keyup)이다. 
  // { } 안엔 감지했을 때 실행되어야 할 함수의 내용을 담는다.

✏️ 고전 이벤트 모델

  • 이벤트를 추가하는 방식은 표준 이벤트 모델 외에 "고전 이벤트 모델" 이 있는데, 이 방식은 onXXX으로 시작하는 속성에 함수를 할당해서 이벤트를 연결한다.
    • 예시:
  document.body.onkeyup = () => {} 
  // HTML 바디 부분에서 'keyup'이라는 이벤트를 감지한다. 
  // () 안에는 전달하고자 하는 인자를, { } 안엔 감지했을 때 실행되어야 할 함수의 내용을 담는다.

✏️ 인라인 이벤트 모델

  • "인라인 이벤트 모델" 은 고전 이벤트 모델처럼 onXXX으로 시작하는 속성 사용하지만, HTML 태그에 직접 추가해서 이벤트를 넣는다.
    • 2000년대부터 2010년대 전까지 주로 사용하고 이젠 많이 사용되진 않지만, 최근에 나온 프론트엔드 프레임워크들이 인라인 이벤트와 표준 이벤트 모델 둘 다 많이 사용하기 때문에 알아두는 것이 좋다.
    • 예시:
<script> // 스크립트 태그 내부에 listener라는 변수 지정
  const listener = (event) => { // 변수에 화살표 함수를 이용해서 (event)라는 인자를 주고, 
  	console.log("keyup") // 이벤트 발생 시 콘솔에 "keyup"이라는 글자가 찍힌다.
  };
</script>

<input onkeyup="listener(event)"></input> 
// script 태그 내부에 정의된 함수(listener)는 html 태그인 input 태그에 "onkeyup" 이 발생될 때 마다 적용된다.


2. 키보드 이벤트와 종류

  • 키보드 이벤트는 크게 3가지가 있다.

    이벤트설명
    keydown키가 눌릴 때 실행. 키보드를 꾹 누르고 있을 때도, 입력될 때도 실행된다.
    keypress키가 입력되었을 때 실행. 기본적으로 keydown과 비슷하다. 하지만 아시아권 문자 사용시 적용할 수 없다.
    keyup키보드에서 키가 떨어질 때 (누르고 손을 뗄 때) 이벤트가 실행된다. 가장 일반적으로 사용된다.
  • 예시: 이벤트가 발생한 횟수 카운트 하기

  <body>
    <script>
      let counter = 0 // 3. 이벤트 발생 횟수를 세기 위해 "counter"라는 변수를 선언하고 0을 할당했다.
      const listener = (event) => { 
      // 2. 이벤트 발생 시 실행될 함수를 상수 "listener"에 할당하고 이벤트 객체를 첫번째 매개변수로 줬다.
        counter++
      // 4. 이벤트 발생 시, "counter"에 할당된 값은 1씩 증가한다.
        console.log(`keypress: ${counter}`) 
      // 5. 이벤트 발생 시, 콘솔에 "keypress: {카운터의 값}"이 출력된다.
      };
    </script>

    <input onkeypress="listener(event)"></input> // 1. 인풋필드에 onkeypress 이벤트를 연결시켰다.
  </body>
  • keydown을 사용할 경우, 키보드가 눌릴 때마다 콘솔에 1이 증가한다.
    • keypress와 다르게, 아시아권 문자도 인식한다.
    • 꾹 누르고 있어도 실행된다.
  • keyup을 사용할 경우, 키보드에서 손이 떨어질 때 콘솔에 1이 증가한다.
    • 아시아권 문자도 인식한다 (한글)
    • 꾹 누르고 있는 경우 횟수가 증가하지 않는다.

✏️ 키보드 키 코드 사용하기

  • 키보트 이벤트 발생 시, 이벤트 객체로 어떤 키를 눌렀는지와 관련된 속성들이 따라온다.
    • 예시:
      이벤트 속성 이름설명
      codecode 속성은 입력한 키를 나타내는 문자열이 들어있다. 의미한다.
      keyCode입력한 키를 나타내는 숫자
      altKeyalt 키를 눌렀는지 boolean 형식으로 확인
      ctrlKeyctrl 키를 눌렀는지 boolean 형식으로 확인
      shiftKeyshift 키를 눌렀는지 boolean 형식으로 확인
<script>
    document.addEventListener("DOMContentLoaded", () => { 
  // DOM 구조 파악이 끝난 이후에 이벤트가 실행된다
      const h1 = document.querySelector("h1");
  // h1 이라는 상수에 쿼리셀렉터를 이용해서 html에 있는 <h1>를 담는다

      const print = (event) => {
        // print 라는 상수에 이벤트가 감지되었을 때 실행될 함수를 담는다. (매개변수로 event 설정)
        let output = ""; 
        // 이벤트 이후 결과값을 output이라는 변수에 담는다.
        output += `alt: ${event.altKey}<br>`;
        // output에 alt 키가 눌렸을 때 "alt: true/false" 가 출력되게 설정하고 줄바꿈 추가
        output += `ctrl: ${event.ctrlKey}<br>`;
        // output에 ctrl 키가 눌렸을 때 "ctrl: true/false" 가 출력되게 설정하고 줄바꿈 추가
        output += `shiftKey: ${event.shiftKey}<br>`;
        // output에 shift 키가 눌렸을 때 "shift: true/false" 가 출력되게 설정하고 줄바꿈 추가
        output += `code: ${
          typeof event.code !== "undefined" ? event.code : event.keyCode
        }<br>`;
        // 만약 event.code의 결과값이 undefined가 아닐 경우 event.code를 출력하고, 아니면 keyCode를 출력한다.
        // event.code = event.altKey와 같은 키코드를 감지하는 이벤트를 의미한다.
        // event.code가 감지되지 않으면 특수키가 아닌 V, B, 3 등과 같은 일반 키기 때문에, 일반키가 출력된다.
        h1.innerHTML = output;
        // HTML 태그 속성을 그대로 사용하면서 아웃풋을 출력한다. 
        // 예시의 경우 전부 h1로 결과값이 출력된다.
      };

      document.addEventListener("keydown", print);
  	  // 키다운 이벤트가 일어날 때 프린트 함수가 실행된다.
      document.addEventListener("keyup", print);
    });
  </script>

  <body>
    <h1></h1>
  </body>
  • 단축키 사용 시 alt, ctrl, shift 등을 사용하기 때문에 특정 키에 관한 키보드 이벤트 속성이 필요하다.
  • 조건문을 같이 사용할 경우, 간단한 키보드 조작이 필요한 게임을 구현할 수도 있다.
    • 키보드 이벤트에 조건문을 사용할 경우, switch 조건문을 사용하는 것이 더 간단하다.
    • 또 다른 예시: 키로 별 움직이기
<script>
    document.addEventListener("DOMContentLoaded", () => {
  // DOM 구조 파악이 끝난 이후에 이벤트가 실행된다
      const star = document.querySelector("h1");
  // star라는 상수에 쿼리셀렉터를 이용해서 html에 있는 <h1>를 담는다
      star.style.position = "absolute";
  // star의 위치값을 absolute로 준다.
  // postion이 상위 요소 내부에 속박되지 않고, 독립된 배치 문맥을 가지게 된다. (viewport 내에서 움직임이 자유롭다)

      let [x, y] = [0, 0]; 
  // x, y가 들어있는 배열에 다른 배열을 이용해서 각각 0을 할당한다.
      const block = 20;
  // block 이라는 상수의 값을 20으로 준다.
      const print = () => {
        star.style.left = `${x * block}px`;
        // star의 위치값을 변경할 수 있도록 x*block px를 값으로 할당한다.
        star.style.top = `${y * block}px`;
        // star의 위치값을 변경할 수 있도록 y*block px를 값으로 할당한다.
      };

      const [left, up, right, down] = [37, 38, 39, 40];
  // 방향키의 키코드는 각 37,38,39,40 이기 때문에, 배열에 할당한다.

      document.body.addEventListener("keydown", (event) => {
        // HTML의 body 내부에서 'keydown' 이벤트를 감지할 때 실행된다. 
        switch (event.keyCode) {
            // 만약 키코드의 이벤트가:
          case left:
            // left키를 눌렀을 때, x의 값은 -1이 된다
            x -= 1; 
            // 빼기 할당이 되어서 left 키를 많이 누를 수록 x의 좌표값이 계속해서 줄어든다.
            break;
          case up:
            // up키를 눌렀을 때, y의 값은 -1이 된다
            y -= 1;
            break;
          case right:
            // right키를 눌렀을 때, x의 값은 +1이 된다
            x += 1;
            break;
          case down:
            // down키를 눌렀을 때, y의 값은 +1이 된다
            y += 1;
            break;
        }
        print();
        // 조건문이 진행될때마다 위에 만들었던 print 함수가 실행된다.
        // print 함수에서 x,y의 값은 block으로 인해 *20px이 되었기 때문에, star의 position을 변경 시킨다.
        // 그래서 키보드 방향에 따라 20px씩 상하좌우로 별이 움직인다.
      });
    });
  </script>

  <body>
    <h1>⭐️</h1>
  </body>


3. 이벤트 발생 객체

  • 코드의 규모가 커지면, 문서 객체 변수를 사용해 문서 객체와 관련된 정보를 추출할 수 없는 경우가 생긴다.
    • 분리 예시:
 <script>
    const listener = (event) => {
      // 4. listener라는 상수에 이벤트가 감지될 경우 생성되는 함수를 할당한다.
        const length = textarea.value.length
        // 5. 함수 내부에 length라는 상수에 textarea에 입력된 값의 길이(숫자)를 담는다
        h1.textcontent = `글자 수: ${length}`
        // 6. textarea에 입력된 글자 수가 html에 있는 h1의 내용으로 표시된다.
    }

    document.addEventListener('DOMContentLoaded', () =>{
      // 1. html의 DOM 파악이 완료되면 이벤트가 실행된다.
        const textarea = document.querySelector('textarea')
        // 2. textarea 라는 변수에 html에 있는 textarea를 담는다
        const h1 = document.querySelector('h1')
        // 3. h1이라는 상수에 html에 있는 h1을 담는다
        textarea.addEventListener('keyup', listener)
      // 7. textarea에 keyup 이벤트가 일어날 경우, listener라는 함수가 실행되도록 한다.
    })
  </script>

  <body>
    <h1></h1>
    <textarea></textarea>
  </body>
  • 1번부터 7번까지 1번 함수 내에서 실행되지 않고, 4,5,6번은 외부 함수에서 실행된다.
    • 이런 경우, 외부 함수에서 이벤트 함수 내부에 있는 상수에 할당한 값에 접근하지 못 해서 참조 에러 (uncaught reference error)가 발생한다.
    • 분리된 경우에 이벤트를 발생시킨 객체에 접근하는 방법은 2가지가 있다.

✏️ event.currentTarget()

  • 해당 이벤트를 갖고 있는 이벤트 핸들러 그 자체를 지칭할 때 사용한다.
  • 이벤트 리스너 내부에서 문서 객체 정보를 추출한 변수에 접근할 수 없을 때 사용한다.
<script>
    const listener = (event) => {
      // 3. listener라는 상수에 이벤트가 감지될 경우 생성되는 함수를 할당한다.
      const length = event.currentTarget.value.length;
      // 4. 함수 내부에 length라는 상수에 textarea에 입력된 값의 길이(숫자)를 담는다
      const h1 = document.querySelector("h1");
      // 5. h1이라는 상수에 html에 있는 h1을 담는다
      // event.currentTarget의 경우, 하나의 이벤트 핸들러에만 붙일 수 있다.
      // 때문에 참조 에러를 피하기 위해 h1은 여기서 선언해야 코드가 에러 없이 실행된다.
      h1.textContent = `글자 수: ${length}`;
      // 6. textarea에 입력된 글자 수가 html에 있는 h1의 내용으로 표시된다.
    };

    document.addEventListener("DOMContentLoaded", () => {
      // 1. html의 DOM 파악이 완료되면 이벤트가 실행된다.
      const textarea = document.querySelector("textarea");
      // 2. textarea 라는 변수에 html에 있는 textarea를 담는다
      textarea.addEventListener("keyup", listener);
      // 7. textarea에 keyup 이벤트가 일어날 경우, listener라는 함수가 실행되도록 한다.
    });
  </script>

  <body>
    <h1></h1>
    <textarea></textarea>
  </body>
  • 원래라면 변수 선언이 함수 외부에서 선언되었기 때문에 참조에러가 생성되어야 하지만, textarea라는 변수가 사용되는 부분에 event.currentTarget을 사용함으로 자동적으로 이벤트가 발생하는 객체가 참조되었다.

✏️ this 키워드의 사용

  • event.currentTarget 외 외부에서 선언된 변수를 참조하기 위해 this 라는 키워드를 사용한다.
    • this 키워드의 경우, 화살표 함수가 아닌 선언적 함수 function() {}를 사용할 때 적용된다.
    • 예시:
<script>
    const listener = function (event) { // 화살표 함수 대신 선언적 함수를 사용했다
      const length = this.value.length; // 참조할 수 없는 변수가 들어간 부분은 this를 사용했다.
      const h1 = document.querySelector("h1");
      h1.textContent = `글자 수: ${length}`;
    };

    document.addEventListener("DOMContentLoaded", () => {
      const textarea = document.querySelector("textarea");
      textarea.addEventListener("keyup", listener);
    });
  </script>

  <body>
    <h1></h1>
    <textarea></textarea>
  </body>
  • event.currentTargetthis 키워드는 프레임워크마다 선호하는 방식이 다르기 때문에 공식 문서 등을 참조해서 어떤 코드가 더 일반적으로 쓰이는지 알아봐야 한다.


4. 글자 입력 양식 이벤트

  • 사용자로부터 어떤 입력을 받을 때 사용하는 요소를 "입력 양식 (form)" 이라고 한다.
    • input, textarea, button, select 등과 같은 html 태그들이 입력 양식에 속한다.

✏️ input 활용하기

  • 예시: 입력 양식을 기반으로 inch <=> cm 단위 변환기 만들기
<script>
    document.addEventListener('DOMContentLoaded', () => {
        const input = document.querySelector('input')
        const button = document.querySelector('button')
        const p = document.querySelector('p')

        button.addEventListener('click', () =>{
          // 버튼에 클릭 이벤트 발생 시 함수가 실행된다.
            const inch = Number(input.value)
            const cm = inch*2.54

            if(isNaN(inch)){
              // 만약 inch에 입력된 값이 숫자가 아닐 경우
                p.textContent = `숫자를 입력해주세요`
                // p태그 부분에 경고 메세지가 생성된다
                return 
              // if문을 사용하는 경우, 조건이 false가 나올 때 else를 사용하지 않을 수 있다.
              // else가 아닌 return을 사용해서 바로 false 일때의 결과값을 출력하는 경우를 "조기 리턴"이라고 한다.
            }
            p.textContent = `${cm}cm`
        })
    })
  </script>

  <body>
    <input>inch</input>
    <button>계산하기</button>
    <p></p>
  </body>

✏️ 드롭다운 목록 활용하기

  • 드롭다운은 기본적으로 select 태그를 사용한다.
    • 예시: 초기값이 설정되어 있는 드롭다운 만들기
<script>
    document.addEventListener("DOMContentLoaded", () => {
      const select = document.querySelector("select");
      const p = document.querySelector("p");

      select.addEventListener("change", (event) => { 
        // 3. 이벤트가 일어날 위치인 select에 addEventListener를 붙이고, 'change' 이벤트를 첫 번째 매개변수로 둔다
        const options = event.currentTarget.options;
        // 4. 일어날 이벤트의 대상자인 options에 event.currentTarget을 지정한다.
        // 5. 드롭다운 설정 시, options 하나만 표시된다.
        const index = event.currentTarget.options.selectedIndex;
        // 6. 'index'라는 상수에 이벤트 대상자인 options에 추가로 'selectedIndex'라는 속성을 부여한다. 
        // 7. 드롭다운으로 선택한 옵션의 값을 의미한다.

        p.textContent = `선택: ${options[index].textContent}`;
        // 8. 사용자가 선택한 옵션의 값이 추출되도록 'options[index]'를 textcontent의 표시된다.
        // 9. 떡볶이 선택 시 "떡볶이"라는 글이 p태그 쪽에 표시된다.
      });
    });
  </script>

  <body>
    <select>
    // 1. select 아래에 options를 둔다.
      <option>떡볶이</option> 
	// 2. 원하는 만큼 옵션의 수를 지정하고 각 옵션에 선택지를 둔다.
      <option>튀김</option>
      <option>순대</option>
      <option>어묵</option>
    </select>
    <p>선택: 떡볶이</p>
  </body>

  • select에 multiple 속성 추가 시, 여러개를 선택할 수 있는 드롭다운이 만들어진다.
    • 다중 선택 시, ctrl 혹은 shift 키를 누른 상태로 선택한다.
    • 예시:
<script>
    document.addEventListener("DOMContentLoaded", () => {
      const select = document.querySelector("select");
      const p = document.querySelector("p");

      select.addEventListener("change", (event) => {
        const options = event.currentTarget.options;
        // 2. 이벤트 대상자인 options에 event.currentTarget을 붙인다.
        const list = [];
        // 3. 다중 선택의 경우 선택 항목이 여러개이기 때문에, 선택된 항목을 담을 빈 배열을 준비한다.

        for (const option of options) {
          // 4. select 내부에 있는 모든 options를 돌아야 한다. 
          // 5. options 속성에는 forEach() 메소드가 없기 때문에, 반복문을 사용한다.
          // 6. p 태그 부분에 인덱스 번호가 아니라 option의 값이 필요해서 for of를 사용한다.
          if (option.selected) {
            // 7. 만약에 선택된 옵션이 있다면
            list.push(option.textContent);
            // 8. 빈 배열에 선택된 option의 text만 추가한다.
          }
        }
        p.textContent = `선택: ${list.join()}`;
        // 9. p 태그에 내용에 추출된 list에 있는 요소들을 합해서 표시한다.
        // 10. 다중 선택 시 떡볶이, 튀김, 순대, 어묵으로 출력
      });
    });
  </script>

  <body>
    <select multiple> // 1. select에 multiple 속성 추가
      <option>떡볶이</option>
      <option>튀김</option>
      <option>순대</option>
      <option>어묵</option>
    </select>
    <p>선택: 떡볶이</p>
  </body>

✏️ 체크박스 활용하기

  • select 사용 시 선택된 요소의 속성이 selected였다면, checkbox 사용 시 선택된 요소의 속성은 checked다.
  • checkbox는 하나만 선택하는 경우 외에도 한번에 여러개를 선택할 때 전달하는 옵션 중 하나다.
    • 예시:
<script>
    document.addEventListener("DOMContentLoaded", () => {
      let [timer, timerID] = [0,0]
      // 2. 구조분해 할당을 이용해서 변수 timer와 timerID에 각각 0 할당
      const h1 = document.querySelector('h1')
      const checkbox = document.querySelector('input')

      checkbox.addEventListener('change', (event) => {
        // 3. checkbox에서 change 이벤트가 일어날 경우 함수 실행 선언
        if (event.currentTarget.checked){
          // 4. 만약 이벤트 대상자 (체크박스)의 속성이 checked라면,

            timerID = setInterval (()=>{
              // 5. timerID에 할당한 함수 setInterval이 실행된다.
                timer += 1
              // 6. setInterval() 실행 시, timer의 값은 더하기 할당으로 1씩 증가하고
                h1.textContent = `${timer}`
              // 7. html에 있는 h1 태그 내용에 초가 표시된다.
            }, 1000)
          	// 5-1. setInterval 함수는 1초 (1000ms)마다 실행된다.
        } else {
          // 8. 만약에 이벤트 대상자 (체크박스)의 속성이 checked가 아니라면
            clearInterval(timerID)
          // 9. timerID를 매개변수로 두고 있는 clearInterval 함수를 실행한다 = setInterval 함수를 초기화한다.
        }
      })

    });
  </script>

  <body>
    <input type = "checkbox"></input>
// 1. 체크박스를 만들기 위해 input에 checkbox 속성 부여
    <span>타이머 활성화</span>
    <h1></h1>
  </body>

✏️ 라디오 버튼 활용하기

  • 체크박스와 비슷한 입력 양식 요소지만, 여러개 중 하나의 옵션만 선택할 수 있을 때 라디오 버튼을 활용한다.
    • 체크박스와 동일하게 선택된 옵션은 checked 속성이 부여된다.
    • 예시:
<script>
    document.addEventListener("DOMContentLoaded", () => {
      const output = document.querySelector("#output");
  // 5. 상수 output에 id값이 output인 html의 요소를 할당
      const radios = document.querySelectorAll("[name=pet]");
  // 6. 상수 radios에 name이 pet인 요소들을 일괄적으로 할당

      radios.forEach((radio) => {
        // 7. 모든 라디오 버튼 확인을 위해 forEach() 메소드 사용
        radio.addEventListener("change", (event) => {
          // 8. 라디오 버튼 하나에 change 이벤트 추가
          const current = event.currentTarget;
          // 9. current라는 상수에 지금 이벤트가 일어난 특정 대상을 할당
          if (current.checked)
            // 10. 만약 current가 선택된 상태면,
            output.textContent = `좋아하는 동물은 ${current.value}입니다.`;
          // 11. output에 해당 내용을 출력한다.
          }
        });
      });
    });
  </script>

  <body>
    <h3>좋아하는 동물을 선택해주세요</h3>
// 1. input 타입에 radio를 설정하고 name과 value 설정
// 2. name으로 모든 라디오 버튼들을 묶어두지 않으면 하나씩 선택할 수 없음 (선택 해제 불가능)
// 3. 라디오 버튼 클릭 시 받아올 값은 value로 설정
    <input type="radio" name="pet" value="강아지" />
    <label for="강아지">강아지</label>
// 4. label의 경우, 라디오 버튼과 묶고싶다면 for에 라디오 버튼의 value를 할당
    <input type="radio" name="pet" value="고양이" />
    <label for="고양이">고양이</label>
    <input type="radio" name="pet" value="햄스터" />
    <label for="햄스터">햄스터</label>
    <input type="radio" name="pet" value="기타" />
    <label for="기타">기타</label>
    <h3 id="output"></h3>
  </body>


4. 기본 이벤트 막기

  • 브라우저에서 마우스 오른쪽 클릭할 때 생성되는 창은 "컨텍스트 메뉴(context menu)" 라고 한다.
  • 컨텍스트 메뉴처럼 이벤트 발생 시 브라우저가 기본적으로 처리해주는 것을 "기본이벤트" 라고 한다.
    • 링크나 제출 버튼을 클릭했을 때 이동하는 것 등이 기본 이벤트다.
    • 기본 이벤트를 제거하고 싶은 경우. preventDefault() 메소드를 사용한다.
    • 예시: 이미지 마우스 오른쪽 클릭 막기
<script>
    document.addEventListener("DOMContentLoaded", () => {
      const img = document.querySelector("img");

      img.addEventListener("contextmenu", (event) => {
        // 1. 이벤트가 발생할 대상자인 img에 addEventListener를 붙이고, 'contextmenu'라는 이벤트를 감지하게 한다.
        event.preventDefault();
        // 2. 해당 이벤트가 감지되었을 때, event.preventDefault() 메소드를 호출시켜 contextmenu를 비활성화한다.
      });
    });
  </script>

  <body>
    <img
      src="https://www.mundoperros.es/wp-content/uploads/2018/02/teckel-saltando.jpg"
      alt="블랙탄 닥스훈트가 들판에서 뛰다가 공중에 있는 순간을 찍은 사진"
    />
  </body>
  • 만약 여러개의 이미지 태그에 대한 마우스 우클릭을 막을 경우:
    • querySelectorAll()를 사용해서 모든 이미지 태그를 선택하고,
    • imgs.forEach((img) =>{ }) 복수형 변수에 forEach()를 돌리고 확인해야할 요소에 img를 넣는다.

  • 또 다른 예시: 체크 시에만 링크 활성화
<script>
    document.addEventListener("DOMContentLoaded", () => {
      let status = false;
  // 1. checked 속성은 boolean 자료형이기 때문에, 체크 여부를 확인하기 위해 false라는 값을 갖고 있는 변수를 지정한다.

      const checkbox = document.querySelector("input");
      checkbox.addEventListener("change", (event) => {
        // 2. 이벤트 대상자를 체크박스로 설정하고, 변경이 있을 경우 이벤트를 감지하도록 한다.
        status = event.currentTarget.checked;
        // 3. 이때 이벤트 대상자의 checked 여부에 status를 재할당한다.
      });

      const link = document.querySelector("a");
      link.addEventListener("click", (event) => {
        // 4. 또 다른 이벤트 대상자인 링크에 클릭 이벤트가 생기면 감지하도록 한다.
        if (!status) {
          // 5. 클릭 이벤트 발생 시 만약 checkbox의 checked 속성이 false라면
          event.preventDefault();
          // 6. 브라우저 기본 이벤트 (링크 이동)을 막는다.
        }
      });
    });
  </script>

  <body>
    <input type="checkbox" />
    <span>링크 활성화</span>
    <br />
    <a href="https://velog.io/@hailey199535">내 벨로그</a>
  </body>


5. localStorage 객체

  • 문서 객체를 조작할 때 웹 브라우저가 추가로 제공하는 기능 (API)을 사용하게 된다.

  • 실제로 브라우저는 웹캠 활성화, 알림 설정, 위치 추적 등 다양한 기능을 제공한다.

  • 이때 사용하는 것이 localStorage 객체다.

    • 웹 브라우저가 기본으로 제공하는 객체고, 페이지를 새로고침 하거나 브라우저를 재실행해도 데이터가 소실되지 않는다.
    • 쿠키와 다르게 로컬스토리지는 서버에 데이터를 전달하지 않는다.
    • 쿠키와 다르게 서버가 HTTP 헤더를 통해 로컬스토리지를 조작할 수 없다.
    • 오리진이 같은 경우, 데이터는 모든 탭과 창에 공유된다.

✏️ localStorage 종류

  1. localStorage.getItem(key)
    • 저장된 값을 추출한다. (키에 해당하는 값을 받아온다)
    • 저장된 값이 없는 경우, 'undefined'가 출력된다.
    • 객체의 속성을 추출하는 일반적인 형태로 localStorage.key 혹은 localStorage[key] 형태로 사용할 수 있다.
  1. localStorage.setItem(key, value)
    • 키-값 페어를 저장한다.
    • 객체에 속성을 지정하는 형태를 사용할 수 있다.
  2. localStorage.removeItem(key)
    • 특정 키와 해당 값을 삭제한다.
  1. localStorage.clear()
    • 저장된 모든 값을 초기화한다.
  1. localStorage.key(index)
    • 인덱스(index)에 해당하는 키를 받아온다
  1. localStorage.length
    • 저장된 항목의 개수를 얻는다.
  1. 예시: localStorage 사용하기
 <script>
    document.addEventListener("DOMContentLoaded", () => {
      const p = document.querySelector("p");
      const input = document.querySelector("input");
      const button = document.querySelector("button");

      const savedValue = localStorage.getItem("input");
   // 1. 인풋에 입력된 값을 추출해서 상수 savedValue에 담는다

      if (savedValue) {
        // 2. 만약 savedValue가 true (스토리지에 무언가가 저장됐다면) 라면
        input.value = savedValue;
        // 3. input의 값을 savedValue로 지정 (저장되어 있는 값을 보여준다)
        p.textContent = `이전 실행 때의 마지막 값: ${savedValue}`;
      }

      input.addEventListener("keyup", (event) => {
        // 4. 인풋에 keyup 이벤트가 생기면 이벤트를 감지한다.
        const value = event.currentTarget.value;
        // 5. value라는 상수에 이벤트 대상자의 값을 담는다
        localStorage.setItem("input", value);
        // 6. 인풋에 입력된 값을 키-값 페어로 저장한다.
        // 여기서 저장된 내용이 위에 조건문에서 getItem을 통해 불러진다.
      });

      button.addEventListener("click", (event) => {
        // 7. 버튼 클릭 시 localStorage에 담겨있던 정보를 삭제시키거
        localStorage.clear();
        input.value = "";
        // 8. 인풋에 써있던 값을 빈칸으로 초기화 한다.
      });
    });
  </script>

  <body>
    <p></p>
    <button>지우기</button>
    <input type="text" />
  </body>
  • 로컬스토리지는 서버에서 접근할 수 없는 저장 공간이기 때문에, 쇼핑몰 장바구니 내역 같은 정보를 localstorage에 주로 저장시킨다.
  • 로컬스토리지는 문자열인 키와 값만 지원하기 때문에 문자열이 아닌 객체나 배열 혹은 그 외 타입의 자료형을 저장하려면 [object Object]로 저장된다.
  • JSON.stringfy()를 이용해서 JSON 형식으로 데이터를 전환한 후에 로컬스토리지에 담고,
  • 데이터를 다시 가져올 경우, JSON.parse()를 사용해서 원래의 데이터 타입으로 복구한다.


출처: 혼자 공부하는 자바스크립트 (한빛미디어)

profile
공부하느라 녹는 중... 밖에 안 나가서 버섯 피는 중... 🍄

0개의 댓글