Hah-nna / Tech_Interview

0 stars 0 forks source link

[js]버블링,캡처링, 이벤트 위임 #39

Open young-02 opened 10 months ago

young-02 commented 10 months ago

이벤트 흐름

HTML 문서의 각 엘리먼트들은 태그 안에 태그가 위치하는 계층적으로 이루어져 있다. 계층적 구조 특징 때문에 요소의 이벤트가 발생할 경우 연쇄적 이벤트 흐름이 일어난다. 전파 방행에 따라 버블링과 캡처링으로 구분한다.

이벤트 전파 흐름 3가지

  1. 캡처링 단계 : 이벤트가 하위 요소로 전파되는 단계
  2. 타킷 단계 : 이벤트가 실제 타깃 요소에 전달되는 단계
  3. 버블링 단계 : 이벤트가 상위 요소로 전파 되는 단계

버블링

자식 요소에서 발생한 이벤트가 바깥 부모 요소로 전파

<div id="ancestor">
    <div id="parent">
        <div id="child"></div>
    </div>
</div>
<script>
    ancestor.addEventListener("click", (e) => {
      console.log('ancestor clicked');
    })
    parent.addEventListener("click", (e) => {
      console.log('parent clicked');
    })
    child.addEventListener("click", (e) => {
      console.log('child clicked');
    })
</script>

버블링

캡쳐링

자식요소에서 발생한 이벤트가 부모요소부터 시작해서 안쪽 자식 요소까지 도달

<div id="ancestor">
    <div id="parent">
        <div id="child"></div>
    </div>
</div>

<script>
    ancestor.addEventListener("click", (e) => {
      console.log('ancestor clicked');
    }, true)
    parent.addEventListener("click", (e) => {
      console.log('parent clicked');
    }, true)
    child.addEventListener("click", (e) => {
      console.log('child clicked');
    }, {capture: true})
</script>

캡처링

이벤트 전파 방지

꼭 필요한 경우를 제외하곤 버블링, 캡처링을 막는 것은 좋지 않다.

e.stopPropagation()

버블링, 캡처링 설정에 따라 이벤트 전파를 막을 수 있다.

ancestor.addEventListener("click", (e) => {
  e.stopPropagation() // 이벤트 전파 방지
  print('ancestor')
})
parent.addEventListener("click", (e) => {
  e.stopPropagation() // 이벤트 전파 방지
  print('parent')
})
child.addEventListener("click", (e) => {
  e.stopPropagation() // 이벤트 전파 방지
  print('child')
})

e.stopImmediatePropagagation()

이벤트 전파 뿐 아니라 같은 요소에 발생한 동일한 이벤트에 대한 다른 이벤트 핸들러의 실행까지 막는다.

child.addEventListener("click", (e) => {

    if(조건)
        e.stopImmediatePropagation()

    print('child')
})
child.addEventListener("click", (e) => {
    print('child 2')
})

e.target

직접 조건 분기를 통해 일일히 지정해 줄 수 있다.

document.body.addEventListener('click', (e) => {
    if (e.target.id === "ancestor") {
        print('ancestor')
    }
    if (e.target.id === "parent") {
        print('parent')
    }
    if (e.target.id === "child") {
        print('child')
    }

});

e.target vs this(e.currentTarget)

<ul id="menu">
  <li><button id="file">파일</button></li>
  <li><button id="edit">편집</button></li>
  <li><button id="view">보기</button></li>
</ul>
<script>
document.getElementById('menu').addEventListener('click',function(e){
    var target = e.target
    if(target.id === 'file'){

    }else if(target.id === 'edit'){

    }else if(target.id === 'view'){

    }
})
</sctipt>

이벤트 위임의 장점

  1. 동적인 엘리먼트에 대한 이벤트 처리가 수월하다
  2. 이벤트 핸들러 관리가 쉽다
  3. 메모리 사용량이 줄어든다.
  4. 메모리 누수 가능성도 줄어든다.