• [JS] 자바스크립트 Event (위임, 전파, 루프)

    2023. 3. 10.

    by. 지은이: 김지은

    728x90

    1. 이벤트(Event)란?

    쉽게 말해 사용자가 웹페이지에서 무언가를 클릭하거나 키를 누르면 그게 바로 이벤트가 발생할 수 있다.

    이런 동작에 의해 웹 페이지 HTML요소들이 변경되거나 반응할 수 있도록 자바스크립트를 이용해서 특정 동작을 수행할 수 있다.

     

    2. HTML 이벤트

    이벤트 종류는 정말 많다. (MDN 문서 참고)

    대체로 많이 사용되는 이벤트는 마우스, 키보드, 포커스, 폼, 윈도우 이벤트 등이 있다.

    • click: 클릭
    • mouseover: 마우스오버
    • mouseout: 마우스 아웃
    • mousedown: 마우스 클릭
    • mouseup: 마우스 뗐을 때
    • mousemove: 마우스 움직였을 때
    • focus: 포커스 이동
    • change: 값 변경
    • submit: submit 버튼을 눌렀을 때
    • reset: reset버튼을 눌렀을 때
    • load: 페이지 로딩이 완료됐을 때
    • scroll: 스크롤바를 움직였을 때
    • ...

     

    3. addEventListener

    addEventListener와 on이벤트명 차이
    더보기

    addEventListener는 보통 하나의 이벤트에 여러개의 이벤트 동작을 수행할 때 사용한다

    on이벤트명은 HTML 요소의 속성을 직접 이벤트 핸들러를 할당하는 방식으로 하나의 이벤트에 여러개의 핸들러를 추가하지 않고 마지막에 등록된 것만 덮어씌워 동작한다.

     

    그렇기 때문에 addEventListener를 사용해서 이벤트 핸들러를 추가하는 것이 좋다.

     

    HTML 요소를 이용해서 버튼을 만들었을 때 우린 그걸 클릭해도 아무 반응이 일어나지 않는다.

    그 버튼을 클릭했을 때 아무것도 설정해주지 않았기 때문

     

    addEventListener 함수는 이벤트 발생을 감지하고 그 처리를 담당하는 함수

    element.addEventListener(이벤트명, 실행할 함수명);

    이렇게 사용하면 되는데 이벤트 핸들러 함수에 매개변수를 추가해 이벤트 발생 시 전달 받게 된다.

    • element: 이벤트를 추가할 HTML 요소
    • 이벤트명: JavaScript에서 발생할 수 있는 이벤트명(클릭, 마우스오버 등)
    • 함수명: 생략 가능, 해당 이벤트가 발생했을 때 실행할 함수명

     

    예를 들어, 클릭 이벤트가 발생했을 때 특정 함수를 실행하려면 다음과 같이 사용할 수 있다.

    HTML 문서에서 id가 'carrot'인 버튼을 찾아 변수 carrot_btn에 할당한다.

    이제 그 버튼을 클릭했을 때 콘솔에 '토끼가 나타났다' 라는 문자열을 출력하고 싶으면

    showText 함수를 만들어서 이벤트 함수 두번째 인자에 전달하면 이벤트 핸들러를 등록할 수 있다.

    두번째 활용방법은 화살표 함수를 사용해서 이벤트 핸들러를 등록하는 방법으로 간단한 함수를 정의할 때 편리하게 사용할 수 있다.

     

    4. removeEventListener

    말 그대로 특정 이벤트 핸들러 제거할 때 사용

    element.removeEventListener(이벤트명, 실행할 함수명);

     

    여기서 주의할 점은 removeEventListener를 호출할 때 두번째 인자로

    addEventListener로 등록된 이벤트 핸들러와 동일한 함수를 지정해줘야한다는 것

    그렇기 때문에 익명함수는 제거할 수 없다!

     

    5. 이벤트 위임, 전파, 루프

    1) 이벤트 위임(Event Delegation)

    이벤트 위임은 여러 요소에 개별적으로 이벤트를 등록하는 대신, 부모 요소에 이벤트를 등록해서 그 안에 포함된 모든 자식 요소의 이벤트를 관리하는 방법을 말한다.

    예를 들어 <ul>요소와 그 하위 <li> 요소로 이루어진 리스트가 있다고 할 때, <ul> 요소에 클릭이벤트를 등록해서 각 항목을 클릭하면

    이벤트 버블링으로 인해 상위 요소에서 이벤트가 발생할때마다 실행이 된다.

    그래서 리스트의 항목이 추가되거나 제거되더라도 이벤트를 따로 처리할 필요가 없어서 코드를 간결하게 유지할 수 있다.

     

    2) 이벤트 전파(Event Propagation)

    이벤트 전파는 이벤트의 부모 - 자식 관계에서 발생하며 이벤트가 부모요소에서 자식요소로, 자식요소에서 부모요소로 전파되는 과정을 말한다.

    • 이벤트 캡처링: 이벤트가 발생한 요소의 최상위 부모 요소부터 시작해서 이벤트가 발생한 요소까지 이벤트 전파
    • 이벤트 버블링: 이벤트가 발생한 요소부터 최상위 부모 요소까지 올라가며 이벤트 전파

    이벤트 전파는 stopPropagation() 메서드를 사용해서 이벤트 전파를 막을 수 있다.

     

    3) 이벤트 루프(Event Loop)

    자바스크립트가 단일 스레드 기반 언어이기 때문에 동시에 하나의 작업만 처리할 수 있다. 

    하지만, 실제로는 동시에 처리가 되는 것처럼 느껴지는게 이벤트 루프를 통해 동시성을 지원하기 때문이다.

     

    이벤트 루프를 이해하려면, 먼저 호출 스택(Call Stack)과 , 태스크 큐(Task Queue)를 알아야한다.

    • Call Stack: 후입선출(LIFO, Last-In-First-Out)으로 가장 최근에 호출된 함수가 가장 먼저 실행되는 구조로, 함수를 호출할 때마다 스택에 쌓이며 함수 실행이 끝나면 스택에서 제거된다.
    •  Task Queue: 선입선출(FIFO, First-In-First-Out) 구조로, 비동기 작업이 완료된 후 실행할 콜백함수들이 이곳에 저장된다.

    그래서 이벤트 루프는 호출 스택과 큐를 감시해서 비동기 작업을 효율적으로 관리한다.

    호출 스택이 비어있을 때 태스크 큐에 있는 콜백함수를 호출 스택으로 이동시켜 실행하는 과정을 반복해서 비동기 작업의 결과를 기다리는 동안에도 다른 작업을 처리할 수 있도록 한다.

     

    코드로 예시를 들자면

    function baz() {
      console.log('baz');
    }
    
    function bar() {
      console.log('bar')
    }
    
    function foo() {
      console.log('foo');
      setTimeout(bar, 0);
      baz();
    }
    
    foo();

    위 코드의 출력결과는 foo, baz, bar 순으로 출력이 된다.

     

    먼저 foo 함수가 호출되어 호출 스택에 추가가 되면서 foo 를 출력한다.

    다음 setTimeout은 비동기 동작이므로 0초로 지정했지만, bar함수가 즉시 실행되지 않고 태스크 큐에 추가된다.

    동시에 baz가 호출되어 baz를 출력 후 foo함수가 종료되면서 호출 스택에서 제거가 되면

    태스크 큐에 있는 bar를 호출 스택으로 이동하여 bar가 출력된다.

     

     

    댓글