์์ฃผ ๋ฐ์ ๋๋ ์ ๋ณด๋ด๊ณ ์๋ค.
์์ฃผ์์ฃผ ๋ฐ์๊ณ ๋นก์ธ์ง๋ง ๋ ๊ทธ๋งํผ ์์ฒญ๋ ์ฑ์ทจ๊ฐ๊ณผ ์ฌ๋ฏธ๋ก ๊ฐ๋์ฐฌ ํ๋ฃจ๋ค์ด๋ค!
์ฐ์ํํ ํฌ์บ ํ 2์ฃผ์ฐจ ๋ฏธ์ ์ vanilla js ์ผ๋ก 'ํฌ๋ ๋ฆฌ์คํธ ๊ตฌํํ๊ธฐ' ์๋ค.
( ์ฐ๋ฆฌ๊ฐ ๊ฐ๋ณ๊ฒ ์๊ฐํ๋ ๊ทธ ํฌ๋ ๋ฆฌ์คํธ(?)๊ฐ ์๋ ํธ๋ ๋ก, ์ง๋ผ ๋ฑ ํ์ ๋๊ตฌ์์ ์ฌ์ฉํ๋ ์นธ๋ฐ ๋ณด๋ ํํ์ ํฌ๋ ๋ฆฌ์คํธ ์๋ค ใ ใ ..๐ )
์ฐ๋ฆฌ ํ์ ํ๋ก์ ํธ์ web component๋ฅผ ๋์ ํ์๊ณ , ์ด ๊ฒฝํ์ ์ฐ๋ฆฌ์๊ฒ ์๋ก์ด ๋์ ์ด์๊ธฐ ๋๋ฌธ์ ๊ทธ ๊ณผ์ ์์ ๊ฒช์๋ ๋ฌธ์ ๋ค๊ณผ ๋ฐฐ์ด์ ๋ค์ ๊ธฐ๋กํ๊ณ ์ ํ๋ค.
web component ๋?
์น ๊ตฌ์ฑ ์์๋ ์ฝ๋์ ๋๋จธ์ง ๋ถ๋ถ์์ ์บก์ํ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฌ์ฉ์ ์ง์ ์์๋ฅผ ๋ง๋ค๊ณ ์น ์ฑ์์ ํ์ฉํ ์ ์๋๋ก ํ๋ ๋ค์ํ ๊ธฐ์ ๋ชจ์ - mdn
mdn ๊ณต์ ๋ฌธ์๋ฅผ ์ดํด๋ณด๋ฉด web component์ ๋ํด ์์ ๊ฐ์ด ์ค๋ช ํ๊ณ ์๋ค. ๋ง ๊ทธ๋๋ก vanilla js ๊ธฐ๋ฐ์ ์ปดํฌ๋ํธ ๊ฐ๋ฐ์ ํ ์ ์๋๋ก ์ง์ํด์ฃผ๋ ๊ธฐ์ ์ด๋ค.
์ฌ์ฉ์๊ฐ ์ง์ ์ปดํฌ๋ํธ๋ฅผ ์ ์ํ๊ณ , ์ ์ํ ์ปดํฌ๋ํธ๋ฅผ ํ์ด์ง ๋ด์์ ์ฌ์ฌ์ฉํ ์ ์๋ค.
react์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ ๋ถ๋ค์๊ฒ๋ ์ด๋๊ฐ ์ต์ํ ๊ทธ๋ฆผ์ด ๊ทธ๋ ค์ง ๊ฒ์ด๋ค. ์ด์ ์ ์ ํต์ ์ธ ๋งํฌ์ ๋ฐฉ์์ ์๊ฐํด๋ณด๋ฉด ํ์ด์ง๋ฅผ ๊ตฌ์ฑํ๋ UI ์์๋ค์ด ์ฌ์ฌ์ฉํ๊ธฐ ํ๋ ๊ตฌ์กฐ๋ผ ๋ณต์กํ๊ณ ๋นํจ์จ์ ์ด์๋๋ฐ web component๋ฅผ ์ฌ์ฉํ๋ฉด react์์ ์ฌ์ฉํ๋ ๋ฐฉ์ ์ฒ๋ผ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด ์ฌ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ์ด๋ค!
web component ๋ ์ฌ์ฉ์ ์ ์ ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ ์ ์๋๋ก ๋ช๊ฐ์ง ๊ธฐ์ ์ ํน์ง์ ๊ฐ์ง๊ณ ์๋ค.
- custom element
- shadowDOM
- HTML <template>, <slot>
๋จผ์ custom element ๋ถํฐ ์ดํด๋ณด์๐ฅ
custom element
ํ์ด์ง์ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ๋ฑ๋กํ๊ธฐ ์ํด ์ฌ์ฉํ๋ API ์ด๋ค.
coustomElementRegistry.define('๋ถ์ฌํ ์์ ์ด๋ฆ', '์์์ ๋์์ ์ ์ํ๋ class ๊ฐ์ฒด', '์์ฑ์ด ํฌํจ๋ ์ต์
')
coustomElementRegistry.define() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์๋ฅผ ์ ์ํ๋ค.
์ด๋ ๋ถ์ฌํ ์์์ ์ด๋ฆ์ kebab-case๋ฅผ ์ฌ์ฉํ์ฌ ๋ ๋จ์ด๋ฅผ ์กฐํฉํ ์ด๋ฆ์ด์ฌ์ผํ๋ค! ( HTML ๊ธฐ๋ณธ ํ๊ทธ์์ ์ถฉ๋ ๋ฐฉ์ง )
//์์์ ์๋๋ฐฉ์ ๋ฐ UI ํ์ ๋ง๋๋ ํด๋์ค ์ ์
class CustomButton extends HTMLElement{
constructor(){
super()
}
//shadowDOM ์ ์ฌ์ฉํ๊ธฐ ์ํด mode 'open'ํด์ค
this.attachShadow({mode:'open'})
const wapper = document.createElement('div')
wapper.setAttribute('class', 'wapper')
const icon = wapper.appendChild(document.creatElement('span')
//shadowRoot์ wrapper ์์๋ฅผ ๋ฃ์ด์ค
this.shadowRoot.append(wrapper)
}
//๋๋ CustomButton ๊ธฐ๋ฐ์ ์ปดํฌ๋ํธ๋ฅผ icon-button ์ด๋ผ๋ ์ด๋ฆ์ผ๋ก ์ ์ํ ๊ป~
customElements.define('icon-button', CustomButton);
//๋ด๊ฐ ์ ์ํ ์์๋ ์๋์ ๊ฐ์ด ํ๊ทธ๋ก ์ฌ์ฉํด์ฃผ๋ฉด ๋๋ค.
<icon-button> </icon-button>
๋๋ต ์์ ๊ฐ์ ๊ตฌ์กฐ๋ก ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๊ทธ๋ผ ์ด์ ์ฌ์ฉ์ ์ ์ ์์์ class ๊ฐ์ฒด๋ฅผ ์ ์ํ๋ฉฐ ์ฌ์ฉํ shadowDOM ์ด๋ ๋ฌด์์ธ์ง ๊ถ๊ธํ ๊ฒ์ด๋ค.
shadowDOM
shadowDOM ์ ๋ด๊ฐ ์ ์ํ ์์๋ฅผ ์บก์ํ ํ๊ธฐ ์ํ ๊ฐ๋ ์ด๋ค. ์์์ style, html ๋ค์ ๊ธฐ๋ฅ์ ๋น๊ณต๊ฐ๋ก ์ ์งํจ์ผ๋ก์จ ๋ฌธ์ ์์ ๋ค๋ฅธ ์์๋ค๊ณผ ์ถฉ๋ํ ์ผ๋ ค ์์ด ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๊ณ ์คํ์ผ์ ์ง์ ํ ์ ์๋ค.
์ฒ์์๋ ์ด ์ค๋ช ์ด ์ดํด๊ฐ ์ ์๋ ์๋ ์๋ค. ๋ด๊ฐ ํ๋ฒ์ ์ดํดํ ์ ์๋ ์์๊ฐ ์๋ค.
<input type='range'/>
input ํ๊ทธ์ type์ 'range'๋ก ์ค์ ํ๋ฉด ์ด๋ค ์์๊ฐ ์ถ๋ ฅ๋ ๊น?
range input ์ ๊ธฐ๋ณธ UI๊ฐ ์ถ๋ ฅ๋๋ค.

์ด์ ๊ฐ๋ฐ์๋๊ตฌ ์ค๋ฅธ์ชฝ ์๋จ์ ํฑ๋๋ฐํด ์ค์ ๋ฒํผ์ ๋๋ฌ ์ค์ ์ ๋ฐ๊ฟ๋ณด์.

preferences ํญ์ Elements ๋ถ๋ถ์ ๋ณด๋ฉด 'show user agent shadow DOM' ์ด ์๋ค. ์ด ์ต์ ์ ์ฒดํฌํด์ฃผ๋ฉด ๊ฐ๋ฐ์๋๊ตฌ์์ ์จ๊ฒจ์ ธ ์๋ shadow DOM ๋ด๋ถ ์์๋ค์ ๋ณผ ์ ์๋ค.

#shadow-root ๊ฐ ๋ณด์ด๊ณ ํด๋ฆญํ๋ฉด ๊ทธ๋์ ์จ๊ฒจ์ ธ ์๋ ์์๋ค์ด ๋ณด์ธ๋ค.
range type์ input ์์๋ 3๊ฐ์ div ์์๋ก ์ด๋ฃจ์ด์ ธ ์๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
์ด๋ ๊ฒ shadowDOM ์ ์ฌ์ฉํ๋ฉด ๋ด๋ถ ์์์ className ์ผ๋ก 'thumb'๋ฅผ ์ฌ์ฉํ์ด๋ ์ธ๋ถ์์ ์ฌ์ฉํ 'thumb'๊ณผ ์ถฉ๋ํ์ง ์๊ณ ๋ ๋ฆฝ์ ์ผ๋ก ๋์ํ ์ ์๊ฒ ๋๋ค.

shadowDOM mdn ๋ฌธ์์์ ๋ณผ ์ ์๋ shadowDOM ๊ตฌ์กฐ์ด๋ค. ์ผ๋ฐ DOM์ ์ฐ๊ฒฐ๋์ด ์๋ shadow host ๋ด๋ถ์ shadow tree๊ฐ ์๊ณ , shadow tree์ ๋ฃจํธ ๋ ธ๋๋ฅผ shadow root๋ผ๊ณ ํ๋ค.
์๊น ์์์์ ๋ดค๋ <icon-button> ์ shadow host, CustomButton์ ๊ฐ์ฅ ์ต์๋จ ์์์ธ wrapper div ๋ฅผ shadow root๋ผ๊ณ ๋ณผ ์ ์๋ค!
attachShadow({mode:'open'}) ์ ํตํด ์ฌ์ฉ์ ์ ์ ์์๋ฅผ shadow Root์ ์ฐ๊ฒฐํ ์ ์๋ค.
shadow.appendChild(์์) ๋๋ shadow.append(์์1, ์์2, ...) ์์ฑํ ๋ชจ๋ ์์๋ฅผ shadow Root์ ์ฐ๊ฒฐํ ์ ์๋ค.
๋ค์ ํฌ์คํ ์์๋ web component๋ฅผ <template>, <slot> ์ ์ฌ์ฉํ์ฌ ์์ฑํ๋ ๋ฐฉ๋ฒ๊ณผ ์ค์ ๋ก ํ๋ก์ ํธ์ ์ฌ์ฉํ๋ custom component ์ ๋ํด ์ด์ผ๊ธฐ ํด๋ณด๊ฒ ๋ค. ๐ซ
'dev > javascript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [ JS ] ๊ฐ์ฒด ์กฐํ ๋ฐฉ๋ฒ Dot notation vs Square-Bracket notation (0) | 2022.04.22 |
|---|