티스토리 뷰

스터디/하브루타 스터디

1. 이벤트

곤이씨 2021. 4. 4. 18:09

내 질문

[Q1] addEventListener의 세번째 인자인 option에는 어떤 옵션들이 있을까요?

options Optional
이벤트 리스너에 대한 특성을 지정하는 옵션 객체입니다. 사용 가능한 옵션은 다음과 같습니다 :
- capture: DOM 트리의 하단에 있는 EventTarget 으로 전송하기 전에, 등록된 listener 로 이 타입의 이벤트의 전송여부를 나타내는 Boolean 입니다.
- once: 리스너를 추가한 후 한 번만 호출되어야 함을 나타내는 Boolean입니다. true이면 호출할 때 listener 가 자동으로 삭제됩니다.
- passive: true일 경우, listener에서 지정한 함수가 preventDefault()를 호출하지 않음을 나타내는 Boolean입니다. passive listener 가 preventDefault()를 호출하면 user agent는 콘솔 경고를 생성하는 것 외의 작업은 수행하지 않습니다.

[Q2] 커스텀 이벤트를 생성하고 사용하는 과정을 설명해주세요

1. 이벤트 생성자로 이벤트 생성 
: let event = new Event(type[, options]);

2. Element.dispachEvent(event)

[Q3] 커스텀 이벤트를 사용해본 경험이 있다면 무슨 상황에서 어떤 목적을 가지고 사용했는지 공유해주세요.

custom confirm을 promise로 작성하여 동기적으로 실행되도록 만들었습니다.

export const customConfirm = (message) => {
  return new Promise((resolve, reject) => {
    $('#app').insertAdjacentHTML('beforeend', confirmTemplate(message));
    $('.confirm-modal').addEventListener('click', ({ currentTarget, target }) => {
      if (currentTarget === target) {
        currentTarget.remove();
        resolve(false);
      }

      if (target.classList.contains('cancel-button')) {
        currentTarget.remove();
        resolve(false);
      }

      if (target.classList.contains('confirm-button')) {
        currentTarget.remove();
        resolve(true);
      }

      return;
    });
  });
};

[Q4] 이벤트 핸들러 어트리뷰트 방식, 이벤트 핸들러 프로퍼티 방식, addEventListener 메서드 방식의 차이를 설명해주세요.

어트리뷰트 방식 (함수 참조가 아닌 함수 호출문 사용!!!!!)
<button onClick="handleClick(event)">버튼</button>

프로퍼티 방식
const $button = document.querySelector('#button')
$button.onClick = handleClick;

addEventListenter 방식
const $button = document.querySelector('#button')
$button.addEventListener('click', handleClick);

브라우저에게 특정 이벤트가 발생하면 특정 함수(이벤트 핸들러)를 호출하도록 브라우저에게
위임(이벤트 핸들러 등록)할 수 있다. 즉, 함수를 언제 호출할지 알 수 없으므로 개발자가 명시적으로 함수를 호출하는 것이 아니라 브라우저에게 함수 호출을 위임하는 것이다.

[Q5] addEventLisenter를 사용했을 때, 이벤트 핸들러에 인자를 전달하는 방법을 설명해주세요.

class App {
  constructor() {
    $('#app').addEventListener('click', this.handleElement.bind(this, 123));
  }

  handleElement(num, event) {
    console.log(this); // App()
    console.log(num); // 123
    console.log(event); // {mouseX: ...}
  }
}

[Q6] 이벤트 객체의 공통 프로퍼티

https://developer.mozilla.org/ko/docs/Web/API/Event

중요한 내용만
- target: 이벤트를 발생시킨 DOM 요소
- currentTarget: 이벤트 핸들러가 바인됭된 DOM 요소
- eventPhase: 이벤트 전파 단계 (0: 이벤트 없음, 1: 캡처링 단계, 2: 타겟 단계, 3: 버블링 단계)
- bubbles: 이벤트를 버블링으로 전파하는지 여부
- cancelable: preventDefault 메서드를 호출하여 이벤트의 기본 동작을 취소할 수 있는지 여부
- defaultPrevented: preventDefault 메서드를 호출하여 이벤트를 취소했는지 여부
- isTrusted: 사용자의 행위에 의해 발생한 이벤트인지 여부 (dispatchEvent 메서드를 통해 인위적으로 발생시킨 이벤트의 경우 false)

그루밍 질문

[Q1] 미션을 진행하면서 이벤트 위임을 자주 사용하는데요, 곤이는 어떤 경우에 이벤트 위임을 사용하는 것이 적합하다고 생각하시나요? 그리고 이벤트 위임을 사용하면 안되는 경우는 어떤 경우라고 생각하시나요?

 저는 보통 이벤트 위임을 동적으로 추가되는 요소들에 대해 사용하는 편입니다.
동적으로 추가되는 요소에 대해 매번 이벤트 리스너를 추가하는 일은 번거로울 뿐 아니라, 성능적으로도 메모리적으로도 불필요합니다. 이 때문에 추가되는 요소들을 감싸는 부모 요소에 이벤트를 설정합니다.
 이벤트가 삭제되는 경우에도 적용 가능
 이벤트 위임은 방어코드를 잘 작성해주어야합니다. 이 때문에 여러개의 이벤트에 대한 이벤트를 위임하는 경우에는 굉장히 복잡하고 다양한 분기가 발생합니다. 따라서, 이벤트 위임을 무조건 사용하기보다는 동적으로 추가되는 요소에 대해서만 적용하는 것이 좋다고 생각합니다.

[Q2] 곤이가 사용해 본 이벤트들 중에서 가장 멋지다고 생각한 이벤트는 무엇인가요? 어떻게 사용했는지 보여주시면서 설명해주시면 더 좋을 것 같아요!

이벤트에 프로미스 적용하기

다른 크루들 질문

[Q4] addEventListener동작에 대한 질문입니다. addEventListener 콜백함수의 this는 누구를 가리키나요?

이벤트를 바인딩한 DOM 요소. 즉, current Target을 가리킨다.
단, class에서는 사용에 주의해야한다.
class에서의 이벤트 핸들러 함수의 this는 생성할 인스턴스를 가리키지 않고 current target을
가리키기 때문에 사용자의 의도와 다르게 동작할 수 있다. 따라서, bind 메서드를 사용해
this가 생성할 인스턴스를 가리키도록 한다.

[Q2] 이벤트 바인딩이 되어 있었던 요소가 DOM 상에서 사라지면 해당 요소에 걸려 있었던 이벤트 리스너는 자동으로 가비지 컬렉션으로 인해 메모리 상에서 제거가 되나요? 아니면 수동으로 개발자가 지워주어야 하나요?

https://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory
https://stackoverflow.com/questions/4337582/do-events-handlers-on-a-dom-node-get-deleted-with-the-node
https://stackoverflow.com/questions/26442041/is-element-removeeventlistener-required-before-element-parentnode-removechild

'스터디 > 하브루타 스터디' 카테고리의 다른 글

6. This  (3) 2021.05.02
5. 변수와 데이터  (0) 2021.04.25
4. 함수  (0) 2021.04.18
3. 비동기  (1) 2021.04.12
2. CSS selector  (0) 2021.04.04