220922(๋ชฉ)
๐ชด ์ฑ์ฅ์ผ์ง 2.0
์ฑ
ํ๋ณตํ ์ด๊ธฐ์ฃผ์์(์จ์ธ ๋ค์ด์ด)
์ ๋ด์ฉ์ ์๊ทน๋ฐ์ ์์ํ๋ ์๋ฐํ ์ฑ์ฅ๊ธฐ๋ก
์ด์์๋ ๊ฝ๊ณผ ์ฃฝ์ ๊ฝ์ ์ด๋ป๊ฒ ๊ตฌ๋ณํ๋๊ฐ?
์ฑ์ฅํ๊ณ ์๋ ๊ฒ์ด ์ด์ ์๋ ๊ฒ์ด๋ค.
์๋ช ์ ์ ์ผํ ์ฆ๊ฑฐ๋ ์ฑ์ฅ์ด๋ค!
๐ณ ํค์๋ (1.0) ์ต๋ํ ๊ฐ๋จํ๊ฒ ์ ๋ฆฌ, ์ถํ์ ๋ณด๋ฉด์ ์ค์ค๋ก ์ค๋ช ๐ ๊ฒฝํ ์์ฃผ๋ก (2.0) ๋จ์ ์ ๋ณด๋ฅผ ์ ๋ฌํ๊ธฐ๋ณด๋ค ๋ฌด์์ ๋ฐฐ์ ๊ณ ์ด๋ป๊ฒ ํด๊ฒฐํ๋์ง ์งง๊ณ ๊ฐ๋จํ๊ฒ ์์ฑํ์
Project
get-shit-done
ํ๋ก์ ํธํ๋ค๊ณ ๋ฐ๋น ์ ์ฑ์ฅ์ผ์ง๋ฅผ ๋ช์ผ ์ฐ์ง ๋ชปํ๋ค.
์ฑ์ฅ์ผ์ง์์๋ ํ๋ก์ ํธ๋ฅผ ํ๋ฉด์ ๋ฐฐ์ด ๊ฒ๋ค์ ๊ฐ๋จํ๊ฒ ๋จ๊ธฐ๊ณ ๋ฐ๋ก project ํ๊ทธ๋ก ์์ธํ ์ ๋ฆฌํ ์์ ์ด๋ค.
๋ชฉํ
- ์น ์ปดํฌ๋ํธ๋ฅผ ํตํ UI ๊ตฌํ
JavaScript
์น ์ปดํฌ๋ํธ
์ง๋ ๋ช ํด ๋์ ์๋ง์ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ ์์ํฌ(๋ผ์ด๋ธ๋ฌ๋ฆฌ)๊ฐ ๋ฑ์ฅํ๋ค.(์ต๊ทค๋ฌ, ๋ทฐ, ๋ฆฌ์กํธ ๋ฑ๋ฑ)
์ด๋ฐ ํ๋ ์์ํฌ๋ค์ ๋ค์ํ ๋ฌธ์ ๋ฅผ ํธํ๊ฒ ํด๊ฒฐํ ์ ์๊ฒ ํด์ฃผ์์ง๋ง, ๋ฉ์น๊ฐ ํฌ๊ธฐ์ ์ฑ์ด ๋ฌด๊ฑฐ์์ง๊ณ ํ๋ ์์ํฌ์ ์ข
์๋ ์ฝ๋๋ฅผ ์์ฐํ๊ฒ ํ๋ค.
์ฆ, ์น ์ปดํฌ๋ํธ๋ ์ด๋ฐ ํ๋ ์์ํฌ๋ ์ข์ง๋ง ๋ธ๋ผ์ฐ์ ์ ํ์ค ๊ธฐ๋ฅ
์ ์ด์ฉํด์ ์ฑ๋ฅ ์ข์ ์ฑ์ ๋ง๋ค์๋ ์ทจ์ง์์ ์์ํ๋ค.
HTML, CSS, JS๋ฅผ ์ปดํฌ๋ํธํํ๊ธฐ ์ํ 4๊ฐ์ ํ์ค์ ๋ฌถ์ด์ ์น ์ปดํฌ๋ํธ๋ผ๊ณ ํ๋ค.
๋ฌผ๋ก ์ด 4๊ฐ์ง๋ฅผ ๋ชจ๋ ๋์์ ์จ์ผ๋ง ํ๋ ๊ฒ์ด ์๋ ์ํ๋ ๊ธฐ๋ฅ๋ง ์ฌ์ฉํ๋ฉด ๋๊ณ ํ๋ ์์ํฌ์ ํจ๊ป ์ฌ์ฉํด๋ ๋๋ค.
4๊ฐ์ง ์ค CustomElements์ ShadowDOM์ ์ง์คํด์ ์ดํด๋ณด์.
CustomElements
๋ง ๊ทธ๋๋ก, ๋ด ๋ง์๋๋ก ์ปค์คํ
ํ ์์
๋ฅผ ์๋ฏธํ๋ค.
๊ฐ์ธ์ ์ผ๋ก ๋ฐ๋ก ์ฝ๋๋ฅผ ๋ณด๋ ํธ์ด ์ดํด๊ฐ ๋น ๋ฅด๊ธฐ์ ์๋ ์ฝ๋๋ฅผ ํตํด ์ ๋ฆฌํ๋ค.
// ์๋์ ๊ฐ์ด HTMLElement๋ฅผ ์์ํ๋ ๊ฐ๋
์ผ๋ก ๋๋ง์ element์ ํด๋์ค ๊ฐ์ฒด๋ฅผ ๋ง๋ ๋ค.
// ์ฐธ๊ณ ๋ก class๋ด์ this๋ ์ปค์คํ
์๋ฆฌ๋จผํธ ๊ทธ ์์ฒด๋ฅผ ๋ฐ์ธ๋ฉํ๋ค.
class JaydenCustom extends HTMLElement {
constructor() {
super();
this.render();
}
// ํ์๋ ์๋์ง๋ง, render์ getTemplate ๋ฉ์๋๋ฅผ ํตํด ์ข๋ ์ํ๋ ํํ์ element๋ฅผ ๋ง๋ค ์ ์๋ค.
render() {
this.innerHTML = this.getTemplate();
}
getTemplate() {
return `
<div></div>
<div></div>
`;
}
/*
connectedCallback: ์ปค์คํ
์๋ฆฌ๋จผํธ๊ฐ ์ถ๊ฐ๋ ๋, ํธ์ถ๋๋ค. ์ฃผ๋ก ์ด๊ณณ์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ค๋ฃฌ๋ค.
์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์ consructor์์๋ ์ด ์์๊ฐ `๋ง๋ค์ด์ง ๋`์ด๊ณ ์ฌ๊ธฐ๋ `์ถ๊ฐ๋ ๋`๋ผ๋ ์ ์ด๋ค.
*/
connectedCallback() {}
// disconnectedCallback: ์ปค์คํ
์๋ฆฌ๋จผํธ๊ฐ ์ ๊ฑฐ๋ ๋, ํธ์ถ๋๋ค. ์ฃผ๋ก ์์์ ์์ฑํ ์ด๋ฒคํธ ๋ฑ์ ์ ๋ณด๋ฅผ ์ง์ธ ๋ ์ฌ์ฉํ๋ค.
disconnectedCallback() {}
/*
static get observedAttributes()์์๋ `๊ฐ์ํ ์์ฑ`์ ์๋ ค์ฃผ๋ ์ญํ ์ ํ๋ค. [] ๋ฐฐ์ด ํํ๋ก ์์ฑ์ ์ ๋ฌํ๋ค.
*/
static get observedAttributes() {
return [];
}
// ์์์ ๊ฐ์ ๋์์ด ๋ ์์ฑ์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์คํ๋๋ค.
attributeChangedCallback(name, oldValue, newValue) {}
// ์๋ฌด๋ ๊ฒ๋ ์ํ๋ ๋ฉ์๋๋ฅผ ์์ฑํ์ฌ ํ์ฉํ ์ ์๋ค.
anything() {}
}
// ๋ฐ๋์ ์ด๋ ๊ฒ ์ปค์คํ
์๋ฆฌ๋จผํธ๋ฅผ ์ ์ํด์ฃผ์ด์ผํ๋ค.
// ๋ํ, ์ปค์คํ
์๋ฆฌ๋จผํธ๋ `aaa-bbb`์ ๊ฐ์ ํ์์ ํ๊ทธ๋ช
์ ๊ฐ๋๋ก ํ๋ค.
customElements.define('jayden-custom', JaydenCustom);
ShadowDOM
๋ธ๋ผ์ฐ์ ์ ๋ ๋๋ง ์์ง์ html์ ํ์ฑํ์ฌ DOM์ ํ์ฑํ๋ค. ์ด ๋, ๊ฐ ์์๋ค์ ๋
ธ๋๋ก์ ์์ฉํ๋ค. ๋ฌธ์ ๋ ๊ฐ ๋
ธ๋๊ฐ ๋
๋ฝ์ ์ธ DOM ์์ญ์ ๊ฐ์ง ๋ชปํ๊ณ ์๋ค๋ ์ ์ด๋ค.
์ด๋ฅผ ํด๊ฒฐํด์ฃผ๋ ๊ฒ์ด Shadow DOM
์ผ๋ก ๋ง ๊ทธ๋๋ก ๋ณด์ด์ง ์๋ DOM์ ๋ง๋ค์ด์ฃผ์ด ๊ฐ ์์๊ฐ ๋
๋ฆฝ์ ์ธ ์คํ์ผ๋ง์ด ๊ฐ๋ฅํ๊ฒ ํด์ค๋ค. ๋ฐ๋ก ์ฝ๋๋ฅผ ๋ณด์.
class JaydenShadow extends HTMLElement {
constructor() {
super();
// this๋ ์ปค์คํ
์๋ฆฌ๋จผํธ๋ฅผ ๋ฐ์ธ๋ฉ, ์ฆ ์ปค์คํ
์๋ฆฌ๋จผํธ์ shadow DOM์ ๋ถ์ฌ์ค๋ค.
this.attachShadow({ mode: 'open');
this.render();
}
render() {
// ์๋์ ๊ฐ์ด shadowDOM์ ์ ๊ทผํ๊ธฐ ์ํด์๋ shadowRoot๋ฅผ ์ด์ฉํด์ผํ๋ค.
this.shadowRoot.innerHTML = this.getTemplate();
}
getTemplate() {
return `
<style>
div {
background-color: tomato;
}
</style>
<div></div>
<div></div>
`;
}
// ์์์ ์ปค์คํ
์๋ฆฌ๋จผํธ ๋ด๋ถ(์ ํํ๋ ์๋์ฐ๋)์ ์ํ div๋ฅผ ์ ์ธํ๊ณ ๋ ๋ฐฐ๊ฒฝ์(tomato) ๊ฐ์ ๊ฐ์ง ์๋๋ค.
// ์ฆ, ์ปค์คํ
์๋ฆฌ๋จผํธ๋ง์ ๋
์์ ์ธ ๊ณต๊ฐ์ ๋ง๋ค ์ ์๋ ๊ฒ์ด๋ค.
connectedCallback() {}
disconnectedCallback() {}
static get observedAttributes() {
return [];
}
attributeChangedCallback(name, oldValue, newValue) {}
}
customElements.define('jayden-shadow', JaydenShadow);
์ด์ธ์๋ Template Element์ HTML Import ๋ฑ์ ์์๊ฐ ์์ง๋ง, ์ 2๊ฐ์ง๊ฐ HTML, CSS, JS๋ฅผ ํ๋์ ์ปดํฌ๋ํธ๋ก ๋ฌถ์ด์ฃผ๋ ํต์ฌ ๊ธฐ๋ฅ์ด์ง ์์๊น ์๊ฐํ๋ค.