이벤트 캡처링, 버블링 그리고 disabled vs readonly

    728x90
    반응형
    SMALL

     

    이벤트 캡처링, 버블링 그리고 disabled vs readonly

    이벤트 흐름 3단계

    DOM에서 이벤트가 발생하면 3단계를 거친다.

    [1. 캡처링] window → document → div → button (위에서 아래로)
         ↓
    [2. 타겟] button (실제 클릭한 요소)
         ↓
    [3. 버블링] button → div → document → window (아래에서 위로)
    

     

     

    기본 동작: 버블링 단계에서 실행

    // 기본 (버블링 단계에서 실행)
    div.addEventListener('click', handler);
    
    // 캡처링 단계에서 실행하려면 명시적으로 설정
    div.addEventListener('click', handler, true);
    

     

     

    캡처링 vs 버블링 실행 순서

    <div id="parent">
      <button id="child">클릭</button>
    </div>
    
    parent.addEventListener('click', () => console.log('부모-캡처링'), true);
    parent.addEventListener('click', () => console.log('부모-버블링'));
    child.addEventListener('click', () => console.log('자식'));
    
    button 클릭 시 출력 순서:
    1. "부모-캡처링"  (캡처링 단계)
    2. "자식"        (타겟 단계)
    3. "부모-버블링"  (버블링 단계)
    

     

    stopPropagation()으로 전파 막기

    캡처링에서 막으면

    parent.addEventListener('click', (e) => {
      e.stopPropagation();
      console.log('부모');
    }, true);
    
    child.addEventListener('click', () => console.log('자식'));
    
    [캡처링] parent → 실행 + 전파 중단
             ❌ child까지 안 내려감
    
    결과: "부모"만 출력
    

     

    버블링에서 막으면

    parent.addEventListener('click', () => console.log('부모'));
    
    child.addEventListener('click', (e) => {
      e.stopPropagation();
      console.log('자식');
    });
    
    [캡처링] parent → child (실행 없이 내려감)
    [타겟] child → 실행 + 전파 중단
    [버블링] ❌ parent까지 안 올라감
    
    결과: "자식"만 출력
    

     

     

    disabled는 다르다

    stopPropagation()은 이벤트를 막는 것이고, disabled는 이벤트 자체가 발생하지 않는다.

    <div onClick={handleClick}>
      <input disabled />
    </div>
    
    input(disabled) 클릭
         ↓
    "이 요소는 disabled네? 이벤트 없음"
         ↓
    끝. 캡처링도 버블링도 없음
    

    부모에 이벤트가 있든, 캡처링으로 설정했든 상관없이 아무 일도 안 일어난다.

     

    disabled vs readonly

    속성 입력 가능 이벤트 발생 버블링
    readonly
    disabled

    readonly일 때

    input(readonly) 클릭
         ↓
    [캡처링] div → input
         ↓
    [타겟] input → 이벤트 발생!
         ↓
    [버블링] input → div → onClick 실행!
    

    disabled일 때

    input(disabled) 클릭
         ↓
    이벤트 없음. 끝.
    

     

     

     

    비유로 정리

    disabled          → 공을 아예 안 던짐
    readonly          → 공을 던짐, 정상 진행
    stopPropagation() → 공을 던졌는데 중간에 막음
    

     

     

    결론

    • 이벤트는 캡처링 → 타겟 → 버블링 순서로 흐른다
    • 기본 이벤트 리스너는 버블링 단계에서 실행된다
    • stopPropagation()은 이벤트 전파를 막는다
    • disabled는 이벤트 자체가 발생하지 않는다
    • 부모에 이벤트 위임하고 자식 입력만 막으려면 → readonly 사용
    728x90
    반응형
    LIST

    댓글