[JavaScript] 5. 이벤트, REST API

rin·2020년 12월 6일
1
post-thumbnail

https://poiemaweb.com/coding

이벤트

개념

브라우저에서의 이벤트란 사용자가 버튼을 클릭하거나 웹페이지가 로드되었을 때와 같은 것인데 브라우저는 이벤트를 감지할 수 있으며 이벤트 발생 시에 이를 통지함으로써 사용자가 웹페이지가 상호작용 할 수 있게 해준다.

이벤트가 발생하기 전에는 실행되지 않다가 이벤트가 발생되면 실행하는 함수를 이벤트 핸들러라 칭한다.

이벤트 루프와 동시성

브라우저는

  • 단일 쓰레드에서
  • 이벤트 드리븐 방식으로

동작한다.

단일 쓰레드이므로 한 번에 하나의 작업만을 처리할 것 같지만, 이벤트 루프를 통해 자바스크립트의 동시성(Concurrency)를 지원한다.

  • Call Stack (호출 스택)
    • 자바스크립트는 단 하나의 Call Stack을 가지고 있다.
    • 함수가 호출되면 순차적으로 Call Stack에 쌓인다.
    • 순차 실행되므로 해당 Task가 종료되기 전까진 다른 Task를 수행할 수 없다.
  • Heap
    • 동적 생성된 객체 인스턴스가 할당되는 영역

비동기 요청(이벤트 포함) 처리는 자바스크립트 엔진을 구동하는 환경인 브라우저(혹은 Node.js)가 담당한다.

  • Event Queue(Task Queue)
    • 비동기 처리 함수의 콜백 함수, 비동기식 이벤트 핸들러, Timer 함수의 콜백 함수가 보관되는 영역
    • 이벤트 루프에 의해 Call Stack이 모두 비어지는 순간 순차적으로 Call Stack으로 이동되어 실행된다.
  • Event Loop 📌
    • Call Stack 내에서 현재 실행중인 task가 있는지, Event Queue에 task가 있는지 반복하여 확인한다.
    • Call Stack이 완전히 비어있다면 Event Queue 내의 task가 Call Stack으로 이동하고 실행된다.

이벤트 핸들러

인라인 이벤트 핸들러 방식

  • 일반 함수로서 호출되므로 이벤트 핸들러 내부의 this는 전역 객체 window를 가리킨다.
<!DOCTYPE html>
<html>
<body>
  <button onclick="myHandler()">Click me</button>
  <script>
    function myHandler() {
      alert('Button clicked!');
    }
  </script>
</body>
</html>

❗️ NOTE
onXXX 꼴의 이벤트는 어트리뷰트의 값으로 함수 호출을 전달한다.

이벤트 핸들러 프로퍼티 방식

  • 이벤트 핸들러는 메소드이므로 이벤트 핸들러 내부의 this는 이벤트에 바인딩된 요소를 가리킨다. 이것은 이벤트 객체의 currentTarget 프로퍼티와 같다.(e.currentTarget으로 접근)

이벤트 핸들러 프로퍼티에 하나의 이벤트 핸들러만을 바인딩 할 수 있다.

<!DOCTYPE html>
<html>
<body>
  <button class="btn">Click me</button>
  <script>
    const btn = document.querySelector('.btn');

    // 이벤트 핸들러 프로퍼티 방식은 이벤트에 하나의 이벤트 핸들러만을 바인딩할 수 있다
    // 첫번째 바인딩된 이벤트 핸들러 => 실행되지 않는다.
    btn.onclick = function () {
      alert('① Button clicked 1');
    };

    // 두번째 바인딩된 이벤트 핸들러
    btn.onclick = function () {
      alert('① Button clicked 2');
    };

  </script>
</body>
</html>

addEventListener 메소드 방식

${EventTarget}.addEventListener(eventType, functionName [, useCapture]);

  • ${EventTarget} : 대상요소
  • eventType : 대상 요소에 바인딩될 이벤트를 나타내는 문자열
  • functionName : 이벤트 발생 시에 호출될 함수명 or 함수 자체
  • useCapture : capture 사용여부 (default: false = Bubbling, true = Capturing)

HTML 요소 뿐만아니라 모든 DOM 요소(HTML, XML, SVG)에 대해 동작한다.

  • 지정한 이벤트 핸들러는 콜백 함수이지만 이벤트 핸들러 내부의 this는 이벤트 리스너에 바인딩된 요소(currentTarget)를 가리킨다. 이것은 이벤트 객체의 currentTarget 프로퍼티와 같다.
<!DOCTYPE html>
<html>
<body>
  <button class="btn">Click me</button>
  <script>
    const btn = document.querySelector('.btn');

    // 첫번째 바인딩된 이벤트 핸들러
    btn.addEventListener('click', function () {
      alert('② Button clicked 1');
    });

    // 두번째 바인딩된 이벤트 핸들러
    btn.addEventListener('click', function () {
      alert('② Button clicked 2');
    });
  </script>
</body>
</html>

이벤트의 흐름

이벤트가 발생하면 계층 구조에 의해 연쇄 반응이 일어나는데, 이 때 이벤트가 전파되는 방향에 따라 구분된다.

  • 버블링(Event Bubbling)
    자식 요소에서 발생한 이벤트가 부모 요소로 전파되는 것
  • 캡처링(Event Capturing)
    자식 요소에서 발생한 이벤트가 부모 요소부터 시작하여 이벤트를 발생시킨 자식요소까지 도달하는 것

버블링과 캡처링은 둘 중에 하나만 발생하는 것이 아니라 캡처링부터 시작하여 버블링으로 종료된다.

이벤트 객체

이벤트 객체는 이벤트를 발생시킨 요소와 발생한 이벤트에 대한 정보를 제공한다. 이벤트가 발생하면 이벤트 객체는 동적으로 생성되며 이벤트를 처리할 수 있는 이벤트 핸들러에 인자로 전달된다

<!DOCTYPE html>
<html>
<body>
  <p>클릭하세요. 클릭한 곳의 좌표가 표시됩니다.</p>
  <em class="message"></em>
  <script>
  function showCoords(e) { // e: event object
    const msg = document.querySelector('.message');
    msg.innerHTML =
      'clientX value: ' + e.clientX + '<br>' +
      'clientY value: ' + e.clientY;
  }
  addEventListener('click', showCoords);
  </script>
</body>
</html>

이벤트 핸들러는 암묵적으로 전달되나, 이벤트 핸들러를 선언할 때 첫번째 매개변수를 명시적으로 선언하여야 한다.

Event Property

namedescription
Event.target실제로 이벤트를 발생시킨 요소
이는 반드시 this와 일치하지는 않는다.
Event.currentTarget이벤트에 바인딩된 DOM 요소를 가리킨다.
지정된 이벤트 핸들러 내부의 this와 이벤트 객체의 currentTarget 프로퍼티는 언제나 일치한다.
Event.type발생한 이벤트의 종류를 나타내는 문자열을 반환한다.
Event.cancelable요소의 기본 동작을 취소 시킬 수 있는지 여부를 Boolean 값으로 반환한다.
e.preventDefault(); <- 기본 동작을 중단시킨다.
Event.eventPhase이벤트 흐름 상에서 어느 단계 (event phase)에 있는지를 반환한다.
0 = 이벤트 없음
1 = 캡쳐링 단계
2 = 타깃
3 = 버블링 단계

이벤트 위임

모든 특정 요소의 동일한 이벤트에 대해 동일한 처리를 구현하고 싶은 경우, 해당 요소들에 n개의 핸들러를 바인딩해야한다. 이는 실행 속도 저하의 원인이 될 뿐만 아니라 코드가 길어져 구현에도 매우 불편하다. 또한 동적으로 요소가 추가되는 경우에는 이벤트 핸들러를 바인딩 할 수 없다.

이벤트 위임은 다수의 자식 요소에 각각 이벤트 핸들러를 바인딩하는 대신 하나의 부모 요소에 이벤트 핸들러를 바인딩하는 방법이다.

  • 이는 이벤트가 이벤트 흐름에 의해 이벤트를 발생시킨 요소의 부모요소에도 영향을 미치기 때문(버블링)에 가능한 것이다.

기본 동작의 변경

이벤트 객체는 요소의 기본 동작과 요소의 부모 요소들이 이벤트에 대응하는 방법을 변경하기 위한 메소드를 가지고 있다.

Event.preventDefault()

폼을 Submit 하거나 링크를 클릭하면 다른 페이지로 이동하게 된다. 이와 같은 요소가 가지고 있는 기본 동작을 중단시키기 위한 메소드이다.

Event.stop Propagation()

이벤트를 처리한 후 부모 요소로 이벤트가 전파되는 것을 중단시키기 위한 메소드이다.

  • 부모 요소에 동일한 이벤트에 대한 다른 핸들러가 지정되어 있을 경우 사용된다.
  • 즉, 부모와 자식 요소의 이벤트를 각각 별도로 처리하기 위해 사용된다.

REST API

REST의 기본 원칙을 성실히 지킨 서비스 디자인을 "Restful하다"고 표현한다.

REST API 중심 규칙

  • URI는 자원을 표현하는데에 집중한다.
    • 리소스명은 동사 << 명사
    • get 같은 행위에 대한 표현이 들어가서는 안된다.
  • 행위에 대한 정의는 HTTP Method를 통해 한다.
    • GET, POST, PUT, DELETE, PATCH
profile
🌱 😈💻 🌱

0개의 댓글