λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ‘¨‍πŸ’» web.dev/js.ts

DOM event.composed (shadow root λ°–μœΌλ‘œ 이벀트 μ „νŒŒμ‹œν‚€κΈ°)

by HandHand 2023. 5. 15.

 

πŸ“Œ CustomEvent κ°€ shadow root λ°–μœΌλ‘œ μ „νŒŒλ˜μ§€ μ•ŠλŠ”λ‹€?

shadow DOM κ³Ό ν•¨κ»˜ μž‘μ—…ν•˜λ‹€λ³΄λ©΄ CustomEvent 둜 μƒμ„±ν•œ μ΄λ²€νŠΈκ°€ shadow DOM boundary λ₯Ό λ²—μ–΄λ‚˜μ„œ μ „νŒŒ λ˜μ§€ μ•ŠλŠ” 이슈λ₯Ό λ§ˆμ£Όν•˜κ²Œ λ˜λŠ”λ°, μ΄λŠ” μ˜λ„λœ λ™μž‘μž…λ‹ˆλ‹€.

 

μ˜ˆμ‹œλ‘œ μ‚΄νŽ΄λ΄…μ‹œλ‹€.

λ‹€μŒκ³Ό 같은 menu μ»΄ν¬λ„ŒνŠΈκ°€ μžˆλ‹€κ³  ν•˜κ² μŠ΅λ‹ˆλ‹€.

μž¬μ‚¬μš©μ„±μ„ μœ„ν•΄ 곡톡 메뉴 λ‘œμ§μ„ 담은 μ»΄ν¬λ„ŒνŠΈμž…λ‹ˆλ‹€.

μ½”λ“œλŠ” λ‹¨μˆœν™”μ‹œμΌ°μ§€λ§Œ, open 속성이 true κ°€ 되면 ν•΄λ‹Ή 메뉴 μ—˜λ¦¬λ¨ΌνŠΈμ˜ overlay μ„ νƒμ‹œμ—

메뉴λ₯Ό λ‹«κΈ° μœ„ν•œ μ»€μŠ€ν…€ 이벀트λ₯Ό λ°œμƒμ‹œν‚€λŠ” ν•Έλ“€λŸ¬λ₯Ό λΆ€μ°©ν•˜λŠ” νλ¦„μœΌλ‘œ μ§„ν–‰λ©λ‹ˆλ‹€.

 

export default class MyMenu extends HTMLElement {
    // ... other logics

    attributeChangedCallback(name, oldValue, newValue) {
        if (name === 'open') {
            this.setOverlayEvent()
        }        
    }

    setOverlayEvent() {
        // ... other logics

        const onCloseHandler = this.onClose.bind(this)
        document.addEventListener('touchstart', onCloseHandler, { once: true })
    }

    onClose() {
        this.dispatchEvent(new CustomEvent('close:menu', { bubbles: true }))
    }
}

 

이제 ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈλ₯Ό ν™•μž₯ν•œ color-menu μ»΄ν¬λ„ŒνŠΈλ₯Ό μ •μ˜ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

export default class MyColorMenu extends MyMenu {
    // ... web component initialize logics
}

 

μ˜ˆμƒν•˜κΈ°λ‘œλŠ” menu μ»΄ν¬λ„ŒνŠΈμ˜ close:menu 이벀트λ₯Ό μƒμœ„ DOM 으둜 λ²„λΈ”λ§μ‹œμΌœμ•Όν•˜λŠ”λ°, μ˜ˆμƒλŒ€λ‘œ λ™μž‘ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

 

πŸ“Œ μ™œ μ΄λ ‡κ²Œ λ™μž‘ν• κΉŒ?

μ΄λŠ” DOM ν‘œμ€€ μŠ€νŽ™μ— μ •μ˜λœ 이벀트의 μ˜΅μ…˜ 객체λ₯Ό μ‚΄νŽ΄λ³΄λ©΄ 힌트λ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

https://developer.mozilla.org/en-US/docs/Web/API/Event/Event

 

Event: Event() constructor - Web APIs | MDN

The Event() constructor creates a new Event object. An event created in this way is called a synthetic event, as opposed to an event fired by the browser, and can be dispatched by a script.

developer.mozilla.org

πŸ’‘Event composed
A boolean value indicating whether the event will trigger listeners outside of a shadow root.
The default is `false`
(see https://developer.mozilla.org/en-US/docs/Web/API/Event/composed for more details)

CustomEvent 의 경우 κΈ°λ³Έ Event μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒμ†ν•˜λ©°, composed κΈ°λ³Έκ°’μœΌλ‘œ false λ₯Ό 가지고 있기 λ•Œλ¬Έμ— shadow root μƒμœ„λ‘œ μ΄λ²€νŠΈκ°€ μ „νŒŒλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

 

πŸ“Œ ν•΄κ²° 방법은?

λ§Œμ•½ shadow root λ°–μœΌλ‘œ CustomEvent λ₯Ό 이벀트λ₯Ό μ „νŒŒμ‹œν‚€κ³  μ‹Άλ‹€λ©΄ 이벀트λ₯Ό 생성해쀄 λ•Œ composed: true λ₯Ό ν•¨κ»˜ 전달해주면 λ©λ‹ˆλ‹€.

 

this.dispatchEvent(
    new CustomEvent('close:menu', { 
        bubbles: true, 
        composed: true // βœ… shadow root λ°–μœΌλ‘œ 전달
    })
)

 

πŸ“Œ 참고자료

Shadow DOM and events

Event: composed property - Web APIs | MDN

λ°˜μ‘ν˜•

πŸ’¬ λŒ“κΈ€