29일차 (3) - javascript (이벤트)

Yohan·2024년 4월 1일
0

코딩기록

목록 보기
42/156
post-custom-banner

2. 이벤트

2-1. 이벤트 기초

  • 브라우저는 클릭, 마우스 이동, 키보드 입력 등이 일어나면 이를 감지하여 특정한 타입의 이벤트를 발생
  • 만약 애플리케이션이 특정 이벤트에 반응하고 싶다면 이벤트에 대응하는 함수를 브라우저에게 알려주어 호출을 위임가능
    -> 이 때 호출될 함수를 이벤트 핸들러

이벤트 타입

  • 마우스 이벤트
  1. click – 요소 위에서 마우스 왼쪽 버튼을 눌렀을 때(터치스크린이 있는 장치에선 탭 했을 때) 발생
  2. dblclick – 요소 위에서 마우스 왼쪽 버튼을 두번 빠르게 눌렀을 때 발생
  3. contextmenu – 요소 위에서 마우스 오른쪽 버튼을 눌렀을 때 발생합니다.
  4. mouseover와 mouseout – 마우스 커서를 요소 위로 움직였을 때, 커서가 요소 밖으로 움직였을 때 발생
  5. mousedown과 mouseup – 요소 위에서 마우스 왼쪽 버튼을 누르고 있을 때, 마우스 버튼을 뗄 때 발생합니다.
  6. mousemove – 마우스를 움직일 때 발생
  • 키보드 이벤트
  1. keydown과 keyup – 사용자가 키보드 버튼을 누르거나 뗄 때 발생
    -폼 요소 이벤트
  2. submit – 사용자가 <form>을 제출할 때 발생
  3. change – 사용자가 <input>과 같은 요소에 값이 변할 때 발생
  4. focus – 사용자가 <input>과 같은 요소에 포커스 할 때 발생
  5. blur – 사용자가 <input>과 같은 요소에 포커스를 해제할 때 발생
    -기타 이벤트
  6. resize – 브라우저 창의 크기를 변경할 때 발생
  7. scroll – 웹페이지 또는 HTML요소를 스크롤할 때 연속적으로 발생

이벤트 핸들러

  • 이벤트 핸들러란 특정 타입의 이벤트가 발생했을 때 브라우저가 실행하는 함수
    -> 사용자가 만든 이벤트 처리 함수를 브라우저에게 위임
    -> 총 3가지 방식이 있음!
  1. 어트리뷰트 방식
  • 이벤트 핸들러를 HTML 요소에 직접 지정하는 방법
  • on + 이벤트 타입 으로 이루어진 속성명을 적고 속성값으로 이벤트 핸들러 함수의 호출문을 적음
  • HTML과 자바스크립트의 분리를 위해 요즘은 사용 X
<div class="box" 
    onmouseleave="boxClickHandler()" 
    onmouseover="makeTextHandler()"></div>
  <div class="box green" ondblclick="makeTextHandler()"></div>
  <div class="box red" onmouseover="growHandler()"></div>
  1. 프로퍼티 방식
  • 이벤트 핸들러를 요소 노드의 프로퍼티로 추가하는 방식
  • HTML과 자바스크립트를 분리하여 코딩할 수 있다는 장점
  • 같은 타입의 이벤트에는 여러 핸들러를 바인딩 할 수 없다는 단점
const $b1 = document.getElementById('b1');
    $b1.onclick = sayHelloHandler; // 함수를 대입할 때는 () X, 함수를 바로 실행할 때는 sayHelloHandler()
    
    const $b2 = document.getElementById('b2');
    $b2.ondblclick = () => {
      $b2.style.width = '150px';
    };

    const $b3 = document.getElementById('b3');
    
    $b3.onmouseover = () => {
      $b3.style.background = 'red';
    };
    $b3.onmouseleave = () => {
      $b3.style.background = 'yellow';
    };
  1. 콜백함수 방식
  • addEventListener 메서드는 첫번째 인수로 이벤트 종류를 나타내는 문자열의 이벤트 타입을 전달 (어떤 이벤트를 할 것인지)
    -> 이 때 접두사 on을 붙이지 않음 !! XXXXXXXX
  • 두 번째 인수로는 이벤트 핸들러 함수를 콜백으로 전달 (이벤트가 발생했을 때 어떤 일이 일어날지)
    -> 이 방법은 동일한 요소에서 동일한 이벤트에 대해 하나 이상의 이벤트 핸들러를 등록 가능
  • 기존 핸들러를 지우고 싶다면 수동으로 지워야함
    -> 단, 반드시 핸들러가 기명함수이어야 함 (이름이 있는 함수)
    const $btn = document.getElementById('btn');

    // 이벤트 핸들러
    const helloHandler = () => alert('알룡??');

    // $btn.onclick = helloHandler;
    $btn.addEventListener('click', helloHandler);
    
    // 기존 핸들러를 지우고 싶으면 수동으로 지워야 함
    // 수동으로 지울때는 반드시 핸들러가 기명함수이어야 함
    $btn.removeEventListener('click', helloHandler);

    $btn.addEventListener('click', () => {
      $btn.style.background = 'aqua';
    });

퀴즈 1

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>

    <style>
      .disappear {
        display: none;
      }
    </style>
  </head>

  <body>
    <button id="hider">텍스트 숨기기!!</button>

    <div class="text">안녕하세요~~</div>

    <script>
      //버튼을 클릭하면 div태그가 숨겨지도록
      //이벤트 핸들러를 구현하세요.
      //힌트) css의 display: none; 사용

      const $btn = document.getElementById("hider");
      const $textBox = document.querySelector(".text");

      $btn.addEventListener("click", () => {
        // textbox에 disappear이 있다면?
        // -> textbox에 disappear 제거하고 '텍스트 숨기기'로 변경
        if ($textBox.classList.contains("disappear")) {
          $textBox.classList.remove("disappear");
          $btn.textContent = "텍스트 숨기기!";
        // textbox에 disappear이 없다면?
        // -> textbox에 disappear 추가하고 '텍스트 보이기'로 변경
        } else { 
          $textBox.classList.add("disappear");
          $btn.textContent = "텍스트 보이기";
        }
      });
    </script>
  </body>
</html>
  • 텍스트가 보인다면 버튼을 눌렀을 때 텍스트가 사라지면서 버튼의 text가 바뀌게함
  • 텍스트가 안보인다면 버튼을 눌렀을 때 텍스트가 나타나면서 버튼의 text가 바뀌게함

퀴즈2

<!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">
    <title>Document</title>
    <style>
        .menu ul {
            margin: 0;
            list-style: none;
            padding-left: 20px;
            display: none;
        }

        .menu .title {
            font-size: 18px;
            cursor: pointer;
            -ms-user-select: none;
            -moz-user-select: -moz-none;
            -khtml-user-select: none;
            -webkit-user-select: none;
            user-select: none;
        }

        .menu .title::before {
            content: '▶ ';
            font-size: 80%;
            color: green;
        }

        .menu.open .title::before {
            content: '▼ ';
        }

        .menu.open ul {
            display: block;
        }
    </style>
</head>

<body>

    <!-- #lunches.menu>span.title+ul>li*4 -->
    <div id="lunches" class="menu">
        <span class="title">추천 메뉴(Click Me!)</span>
        <ul>
            <li>돈까스</li>
            <li>군만두</li>
            <li>볶음밥</li>
            <li>마파두부</li>
        </ul>
    </div>


    <script>
        /*
        CSS와 JS를 적절히 사용하여 처음에는 ul이 보이지 않다가    
        추천 점심 메뉴를 클릭하면 나타나도록 이벤트를 구현하세요.
        */
        const $lunches = document.getElementById('lunches');
        const $title = $lunches.querySelector('.title');

        $title.addEventListener('click', function () {
            //toggle: 해당클래스가 없으면 추가, 있으면 제거
            $lunches.classList.toggle('open');
        });        
    </script>

</body>

</html>
  • toggle 메서드를 통해 클릭했을 때 open 클래스가 없으면 추가, 있으면 삭제 시키면서 메뉴가 뜨게함

퀴즈3

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .dropdown {
        width: fit-content;
        margin: 0 auto;
        position: relative;
      }

      .dropdown .btn {
        padding: 10px 40px;
        font-size: 20px;
        background: brown;
        color: wheat;
      }

      #drop-content {
        display: none;
        position: absolute;
        z-index: 99;
      }

      #drop-content a {
        display: block;
        font-size: 20px;
        background: #dfdfdf;
        color: black;
        text-decoration: none;
        padding: 10px 36px;
        margin-top: 2px;
      }

      #drop-content a:hover {
        background: rgb(61, 60, 60);
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div class="dropdown">
      <button class="btn">Drop</button>
      <div id="drop-content">
        <a href="#">Menu1</a>
        <a href="#">Menu2</a>
        <a href="#">Menu3</a>
        <a href="#">Menu4</a>
        <a href="#">Menu5</a>
      </div>
    </div>

    <script>
    /*
        mouseover, mouseout    : 버블링 있음
        mouseenter, mouseleave : 버블링 없음
    */
      // mouseover, mouseleave 사용 (mouseenter x)
      const $btn = document.querySelector(".btn");
      const $drop_content = document.getElementById("drop-content");

      // mouseover했을 때 -> 메뉴가 뜨게
      $btn.addEventListener("mouseover", () => {
        $drop_content.style.display = 'block';
      }); 
      
      // mouseleave했을 때 -> 메뉴 사라지게
      $drop_content.parentElement.addEventListener("mouseleave", () => {
        $drop_content.style.display = 'none';
      });
    </script>
  </body>
</html>
  • mouseover를 통해 마우스를 올리면 메뉴가 뜨고, mouseleave를 통해 마우스를 바깥으로 빼면 메뉴가 사라지게함

퀴즈4

<!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>
    <input
      type="text"
      id="colorInput"
      placeholder="색상 이름이나 HEX 코드를 입력하세요"
    />
    <div id="warning" style="color: red; display: none">
      유효하지 않은 색상입니다!
    </div>

    <script>
      const $input = document.getElementById("colorInput");
      const $warning = document.getElementById("warning");

      // change 이벤트는 입력이 끝났을 때
      // input 이벤트는 한글자 입력할 때 마다 확인됨
      $input.addEventListener("input", () => {
        // console.log($input.value);
        // document.body - body 접근 방법
        document.body.style.background = $input.value;

        // 입력값이 이상하다?
        if (
          document.body.style.background !== $input.value || $input.value === "")
          {
            $warning.style.display = "block";
        } else {
          $warning.style.display = "none";
        }
      });
    </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>Document</title>
    <style>
      .wrap {
        width: 100%;
        height: 100vh;
      }
      .comment {
        color: red;
        display : none;
      }
    </style>
  </head>
    <div class="wrap">
      <input class="input" type="text" placeholder="색상 이름이나 HEX 코드를" />
      <div class="comment">유효하지 않은 색상입니다!</div>
    </div>
    
    <script>
      const $wrap = document.querySelector(".wrap");
      const $input = document.querySelector(".input");
      const $comment = document.querySelector(".comment");

      $input.addEventListener("change", () => {
        if($input.value) {
          $comment.style.display = 'none';
          $wrap.style.background = $input.value;
        } else {
          $comment.style.display = 'block';
        }
      });
    </script>
  </body>
</html> -->
  • change 이벤트는 입력이 끝났을 때 확인
  • input 이벤트는 한 글자씩 입력할 때 마다 확인
  • 전체에 색을 넣는 법 : document.body.style.background
profile
백엔드 개발자
post-custom-banner

0개의 댓글