DOM
#
DOM(Document Object Model)#
DOM treeDOM tree๋ ๋ค ์ข ๋ฅ์ ๋ ธ๋๋ก ๊ตฌ์ฑ๋๋ค.
- ๋ฌธ์ ๋ ธ๋(Document Node)
ํธ๋ฆฌ์ ์ต์์์ ์กด์ฌํ๋ฉฐ ๊ฐ๊ฐ ์์, ์ดํธ๋ฆฌ๋ทฐํธ, ํ ์คํธ ๋ ธ๋์ ์ ๊ทผํ๋ ค๋ฉด ๋ฌธ์ ๋ ธ๋๋ฅผ ํตํด์ผ ํ๋ค. ์ฆ, DOM tree์ ์ ๊ทผํ๊ธฐ ์ํ ์์์ (entry point)์ด๋ค.
- ์์ ๋ ธ๋(Element Node)
์์ ๋ ธ๋๋ HTML ์์๋ฅผ ํํํ๋ค. HTML ์์๋ ์ค์ฒฉ์ ์ํด ๋ถ์ ๊ด๊ณ๋ฅผ ๊ฐ์ง๋ฉฐ ์ด๋ถ์ ๊ด๊ณ๋ฅผ ํตํด ์ ๋ณด๋ฅผ ๊ตฌ์กฐํํ๋ค. ๋ฐ๋ผ์ ์์ ๋ ธ๋๋ ๋ฌธ์์ ๊ตฌ์กฐ๋ฅผ ์์ ํ๋ค๊ณ ๋ง ํ ์ ์๋ค. ์ดํธ๋ฆฌ๋ทฐํธ, ํ ์คํธ ๋ ธ๋์ ์ ๊ทผํ๋ ค๋ฉด ๋จผ์ ์์ ๋ ธ๋๋ฅผ ์ฐพ์ ์ ๊ทผํด์ผ ํ๋ค. ๋ชจ๋ ์์ ๋ ธ๋๋ ์์๋ณ ํน์ฑ์ ํํํ๊ธฐ ์ํด HTMLElement ๊ฐ์ฒด๋ฅผ ์์ํ๊ฐ์ฒด๋ก ๊ตฌ์ฑ๋๋ค. (๊ทธ๋ฆผ: DOM tree์ ๊ฐ์ฒด ๊ตฌ์ฑ ์ฐธ๊ณ )
- ์ดํธ๋ฆฌ๋ทฐํธ ๋ ธ๋(Attribute Node)
์ดํธ๋ฆฌ๋ทฐํธ ๋ ธ๋๋ HTML ์์์ ์ดํธ๋ฆฌ๋ทฐํธ๋ฅผ ํํํ๋ค. ์ดํธ๋ฆฌ๋ทฐํธ ๋ ธ๋๋ ํด๋น ์ดํธ๋ฆฌ๋ทฐํธ๊ฐ ์ง์ ๋ ์์์ ์์์ด ์๋๋ผ ํด๋น ์์์ ์ผ๋ถ๋ก ํํ๋๋ค. ๋ฐ๋ผ์ ํด๋น ์์ ๋ ธ๋๋ฅผ ์ฐพ์ ์ ๊ทผํ๋ฉด ์ดํธ๋ฆฌ๋ทฐํธ๋ฅผ ์ฐธ์กฐ, ์์ ํ ์ ์๋ค.
- ํ ์คํธ ๋ ธ๋(Text Node)
ํ ์คํธ ๋ ธ๋๋ HTML ์์์ ํ ์คํธ๋ฅผ ํํํ๋ค. ํ ์คํธ ๋ ธ๋๋ ์์ ๋ ธ๋์ ์์์ด๋ฉฐ์์ ์ ์์ ๋ ธ๋๋ฅผ ๊ฐ์ง ์ ์๋ค. ์ฆ, ํ ์คํธ ๋ ธ๋๋ DOM tree์ ์ต์ข ๋จ์ด๋ค.
#
DOM Query / Traversing (์์๋ก ์ ๊ทผ)#
ํ๋์ ์์ ๋ ธ๋ ์ ํ(DOM Query)#
document.getElementById(id)id
์์ฑ ๊ฐ์ผ๋ก ์์ ๋ ธ๋๋ฅผ ํ ๊ฐ ์ ํํ์ฌ ๋ฐํ, ์ฌ๋ฌ ๋ ธ๋๊ฐ ์๋ ๊ฒฝ์ฐ ์ฒซ๋ฒ์งธ์์๋ง ๋ฐํHTMLElement๋ฅผ ์์๋ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ค.
๐ ์๋์ ์์ ๋ถํฐ ๋ชจ๋ class="red" ์ธ ์์๋ ์์์ด red ๋ผ๋ css ์ค์ ๊ณผ ๋ค์์ html ์์๋ค์ ๊ณ ์ ํด๋๊ณ ์ฌ์ฉํ๋ค.
.red { color: red;}
<h1>๋๋ฌผ๋์ฅ</h1><p class="dog">๊ฐ์์ง</p><ul> <li id="cocker" class="red">์ฝ์นด</li> <li id="sichu" class="red">์์ธ</li> <li id="poodle" class="red">ํธ๋ค</li></ul><p class="cat">๊ณ ์์ด</p><ul> <li id="sphinx" class="black">์คํํฌ์ค</li> <li id="russian" class="black">๋ฌ์์</li> <li id="persian" class="black">ํ๋ฅด์์</li></ul>
const elem = document.getElementById('sphinx');elem.className = 'red';
- ๊ฒฐ๊ณผ
#
document.querySelector(cssSelector)CSS ์ ํ์๋ก ์์ ๋ ธ๋ ํ ๊ฐ ์ ํํ์ฌ ๋ฐํ, ์ฌ๋ฌ ๋ ธ๋๊ฐ ์๋ ๊ฒฝ์ฐ ์ฒซ๋ฒ์งธ ์์๋ง ๋ฐํ
HTMLElement๋ฅผ ์์๋ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ค.
const elem = document.querySelector('#sphinx');elem.className = 'red';
#
์ฌ๋ฌ ๊ฐ์ ์์ ๋ ธ๋ ์ ํ(DOM Query)#
document.getElementsByClassName(class)class
์์ฑ ๊ฐ์ผ๋ก ์์ ๋ ธ๋๋ฅผ ๋ชจ๋ ์ ํ ํ๋ค. ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถํ์ฌ ์ฌ๋ฌ class๋ฅผ์ง์ ํ ์ ์๋ค.HTMLCollection ์ ๋ฆฌํดํ๋ค. (live)
const elems = document.getElementsByClassName('black');for (let i = 0; i < elems.length; i++) { elems[i].className = 'red';}
- ๊ฒฐ๊ณผ
์ ์์ ์ ์คํ ๊ฒฐ๊ณผ๊ฐ ์ด์ํ ๊ฒ์ ๋ณผ ์ ์๋๋ฐ, getElementsByClassName ๋ฉ์๋์๋ฐํ๊ฐ์ธ HTMLCollection์ด ์ค์๊ฐ์ผ๋ก Node์ ์ํ ๋ณ๊ฒฝ์ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ฆ loop๊ฐ ์คํ๋๋ฉด์, elems์ className ์กฐ๊ฑด์ ๋ถํฉ๋์ง ์๋ ์์๋ค์ด ์ ๊ฑฐ๋๋ฉด์ elems ๋ฐฐ์ด์ ๊ธธ์ด๊ฐ ๋ณ๋๋๊ธฐ ๋๋ฌธ์ ๋ฃจํ๊ฐ ์ ๋๋ก ์คํ๋์ง ์๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค
๋ฐ๋ณต๋ฌธ์ ์ญ๋ฐฉํฅ์ผ๋ก ๋๋ฆฐ๋ค.
while ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ๋ฉด์, elems์ ์์๊ฐ ๋จ์์์ง ์์ ๋๊น์ง ๋ฐ๋ณตํ๋ค.
const elems = document.getElementsByClassName('black');
while (elems.length > 0) { // elems์ ์์๊ฐ ๋จ์ ์์ง ์์ ๋๊น์ง ๋ฌดํ๋ฐ๋ณต elems[0].className = 'red';}
- HTMLCollection์ ๋ฐฐ์ด๋ก ๋ณ๊ฒฝํ๋ค. (๊ถ์ฅ)
const elems = document.getElementsByClassName('black');
[...elems].forEach((elem) => (elem.className = 'red'));
- querySelectorAll ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค.
#
document.getElementsByTagName(tagName)์ง์ ๋ CSS ์ ํ์๋ฅผ ์ฌ์ฉํ์ฌ ์์ ๋ ธ๋๋ฅผ ๋ชจ๋ ์ ํํ๋ค
NodeList(non-live) ๋ฅผ ๋ฆฌํดํ๋ค.
NodeList๋ HTMLCollection๊ณผ ๋ฌ๋ฆฌ non-live ์ด๊ธฐ ๋๋ฌธ์, loop ์์์ length์ ๋ณํ๊ฐ ์ผ์ด๋์ง ์๋๋ค.
const elems = document.querySelectorAll('.black');elems.forEach((elem) => (elem.className = 'red'));
#
document.getElementsByTagName(tagName)ํ๊ทธ ์ด๋ฆ์ผ๋ก ์์ ๋ ธ๋๋ฅผ ๋ชจ๋ ์ ํํ๋ค
HTMLCollection (live)์ ๋ฆฌํดํ๋ค
const elems = document.getElementsByTagName('li');[...elems].forEach((elem) => (elem.className = 'red'));
#
DOM Traversing(ํ์)๊ธฐ์ค์ด ๋๋ ๋ ธ๋์ ๊ด๊ณ๋ฅผ ๊ฐ๊ณ ์๋ ๋ ธ๋๋ก ์ด๋ํ๋ฉด์ ํ์ํ ์ ์๋ค.
#
parentNode๋ถ๋ชจ ๋ ธ๋๋ฅผ ํ์ํ๋ค.
HTMLElement๋ฅผ ์์๋ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ค.
const elem = document.querySelector('#sphinx');elem.parentNode.className = 'red';
#
firstChild, lastChild์์ ๋ ธ๋๋ฅผ ํ์ํ๋ค
HTMLElement๋ฅผ ์์๋ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ค.
const elem = document.querySelector('ul');elem.firstChild.className = 'black';elem.lastChild.className = 'black';
์์ ์์ ๋ฅผ ์คํํด๋ณด๋ฉด ์ ๋์ํ์ง ์๋๋ฐ, IE๋ฅผ ์ ์ธํ ๋๋ถ๋ถ์ ๋ธ๋ผ์ฐ์ ๋ค์ด ์์ ์ฌ์ด์ ๊ณต๋ฐฑ ๋๋ ์ค๋ฐ๊ฟ ๋ฌธ์๋ฅผ ํ ์คํธ ๋ ธ๋๋ก ์ทจ๊ธํ์ฌ ์ฒซ๋ฒ์งธ ์์ ๋ ธ๋, ๋ง์ง๋ง ์์ ๋ ธ๋๋ฅผ HTML ์์๋ก ํ๋จํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
- HTML์ ๊ณต๋ฐฑ์ ์ ๊ฑฐํ๋ค.
<ul> <li id="cocker" class="red">์ฝ์นด</li> <li id="sichu" class="red">์์ธ</li> <li id="poodle" class="red">ํธ๋ค</li></ul>
jQuery: .prev() ์ jQuery: .next() ๋ฅผ ์ฌ์ฉํ๋ค.
๋๋ firstElementChild, lastElementChild๋ฅผ ์ฌ์ฉํ๋ค.
#
hasChildNodes()- ์์ ๋ ธ๋๊ฐ ์๋์ง ํ์ธํ๊ณ Boolean ๊ฐ์ ๋ฐํํ๋ค.
#
childNodes์์ ๋ ธ๋์ ์ปฌ๋ ์ ์ ๋ฐํํ๋ค.
ํ ์คํธ ์์๋ฅผ ํฌํจํ ๋ชจ๋ ์์ ์์๋ฅผ ๋ฐํํ๋ค.
NodeList(non-live)๋ฅผ ๋ฆฌํดํ๋ค.
#
children์์ ๋ ธ๋์ ์ปฌ๋ ์ ์ ๋ฐํํ๋ค. ์์ ์์ ์ค์์ Element type ์์ ๋ง์ ๋ฐํํ๋ค.
HTMLCollection(live)๋ฅผ ๋ฆฌํดํ๋ค.
const elem = document.querySelector('ul');
if (elem.hasChildNodes()) { console.log(elem.childNodes);
console.log(elem.children); [...elem.children].forEach((el) => console.log(el));}
#
previousSibling, nextSiblingํ์ ๋ ธ๋๋ฅผ ํ์ํ๋ค. text node๋ฅผ ํฌํจํ ๋ชจ๋ ํ์ ๋ ธ๋๋ฅผ ํ์ํ๋ค.
HTMLElement๋ฅผ ์์๋ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ค.
#
previousElementSibling, nextElementSiblingํ์ ๋ ธ๋๋ฅผ ํ์ํ๋ค. ํ์ ๋ ธ๋ ์ค์์ Element type ์์๋ง์ ํ์ํ๋ค.
HTMLElement๋ฅผ ์์๋ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ค.
#
DOM Manipulation (์กฐ์)๋ ธ๋์ ๋ํ ์ ๋ณด๋ ๋ค์๊ณผ ๊ฐ์ ํ๋กํผํฐ๋ฅผ ํตํด ์ ๊ทผํ ์ ์๋ค.
#
nodeName๋ ธ๋ | ํ๋กํผํฐ ๊ฐ |
---|---|
๋ฌธ์ ๋ ธ๋(document node) | #document |
์์ ๋ ธ๋(element node) | ํ๊ทธ ์ด๋ฆ(์์ด๋ก ๋๋ฌธ์) |
์์ฑ ๋ ธ๋(attribute node) | ์์ฑ ์ด๋ฆ |
ํ ์คํธ ๋ ธ๋(text node) | #text |
#
nodeType๋ ธ๋ | ํ๋กํผํฐ ๊ฐ |
---|---|
์์ ๋ ธ๋(element node) | 1 |
์์ฑ ๋ ธ๋(attribute node) | 2 |
ํ ์คํธ ๋ ธ๋(text node) | 3 |
์ฃผ์ ๋ ธ๋(comment node) | 8 |
๋ฌธ์ ๋ ธ๋(document node) | 9 |
#
nodeValue๋ ธ๋ | ํ๋กํผํฐ ๊ฐ |
---|---|
์์ ๋ ธ๋(element node) | null |
์์ฑ ๋ ธ๋(attribute node) | ํด๋น ์์ฑ์ ์์ฑ ๊ฐ |
ํ ์คํธ ๋ ธ๋(text node) | ํด๋น ํ ์คํธ ๋ฌธ์์ด |
#
ํ ์คํธ ๋ ธ๋์์ ์ ๊ทผ/์์ ์์์ ํ ์คํธ๋ ํ ์คํธ ๋ ธ๋์ ์ ์ฅ๋์ด ์๋ค. ํ ์คํธ ๋ ธ๋์ ์ ๊ทผํ๋ ค๋ฉด ๋ค์์ ์์์ ๋ฐ๋ผ์ผ ํ๋ค.
ํด๋น ํ ์คํธ ๋ ธ๋์ ๋ถ๋ชจ ๋ ธ๋๋ฅผ ์ ํ
firstChild ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธ ๋ ธ๋๋ฅผ ํ์
ํ ์คํธ ๋ ธ๋์ nodeValue๋ฅผ ์ด์ฉํ์ฌ ํ ์คํธ ์ทจ๋
nodeValue๋ฅผ ์ด์ฉํ์ฌ ํ ์คํธ ์์
const elem = document.querySelector('ul');console.dir(elem); // HTMLElement: ulconsole.log(elem.nodeName); // ULconsole.log(elem.nodeType); // 1: Element nodeconsole.log(elem.nodeValue); // null
const firstDog = elem.firstElementChild;console.log(firstDog.nodeName); // LIconsole.log(firstDog.nodeType); // 1: Element nodeconsole.log(firstDog.nodeValue); // null
const textNode = firstDog.firstChild;console.log(textNode.nodeName); // #textconsole.log(textNode.nodeType); // 3: Text nodeconsole.log(textNode.nodeValue); // ์ฝ์นดtextNode.nodeValue = 'ํฌ๋ฉ๋ฆฌ์';
#
์์ฑ ๋ ธ๋์์ ์ ๊ทผ/์์ ์์ฑ ๋ ธ๋๋ฅผ ์กฐ์ํ ๋ ๋ค์ ํ๋กํผํฐ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
#
classNameclass ์์ฑ์ ๊ฐ์ ์ทจ๋ ๋๋ ๋ณ๊ฒฝํ๋ค. className ํ๋กํผํฐ์ ๊ฐ์ ํ ๋นํ๋ ๊ฒฝ์ฐ class ์์ฑ์ด ์์ผ๋ฉด class ์์ฑ์ ์์ฑํ๊ณ ์ง์ ๋ ๊ฐ์ ์ค์ ํ๋ค. class ์์ฑ์ ๊ฐ์ด ์ฌ๋ฌ ๊ฐ์ผ ๊ฒฝ์ฐ ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถ๋ ๋ฌธ์์ด์ด ๋ฐํ๋๋ฏ๋ก String ๋ฉ์๋ split(' ')
์ ์ฌ์ฉํ์ฌ ๋ฐฐ์ด๋ก ๋ณ๊ฒฝํ์ฌ ์ฌ์ฉํ๋ค.
const elems = document.querySelectorAll('li');
[...elems].forEach((elem) => { if (elem.className === 'red') { elem.className = 'black'; }});
#
classListadd, remove, item, toggle, contains, replace ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค.
const elems = document.querySelectorAll('li');
[...elems].forEach((elem) => { if (elem.classList.contains('black')) { elem.classList.replace('black', 'red'); }});
#
idid
์์ฑ์ ๊ฐ์ ์ทจ๋ ๋๋ ๋ณ๊ฒฝํ๋ค.id
์์ฑ์ ๊ฐ์ ํ ๋นํ๋ ๊ฒฝ์ฐ,id
์์ฑ์ด ์กด์ฌํ์ง ์์ผ๋ฉดid
์์ฑ์ ์์ฑํ๊ณ ์ง์ ๋ ๊ฐ์ ์ค์ ํ๋ค.
const heading = document.querySelector('h1');
console.dir(heading);console.log(heading.firstChild.nodeValue);
heading.id = 'heading';console.log(heading.id); // heading
#
hasAttribute(attribute)์ง์ ํ ์์ฑ์ ๊ฐ๊ณ ์๋์ง ๊ฒ์ฌํ๋ค.
Return : Boolean
#
getAttribute(attribute)์์ฑ์ ๊ฐ์ ์ทจ๋ํ๋ค
Return : String
#
setAttribute(attribute, value)์์ฑ๊ณผ ์์ฑ์ ๊ฐ์ ์ค์ ํ๋ค.
Return : undefined
#
removeAttribute(attribute)์ง์ ํ ์์ฑ์ ์ ๊ฑฐํ๋ค
Return : undefined
const elems = document.querySelectorAll('li');
elems.forEach((elem) => { if (elem.hasAttribute('class')) { console.log(elem.getAttribute('id')); }});
const sphinx = document.getElementById('sphinx');sphinx.setAttribute('class', 'red');
const sichu = document.getElementById('sichu');sichu.removeAttribute('class');console.log(sichu.hasAttribute('class'));
#
HTML ์ฝํ ์ธ ์กฐ์(Manipulation)#
textContent์์์ ํ
์คํธ ์ฝํ
์ธ ๋ฅผ ์ทจ๋ ๋๋ ๋ณ๊ฒฝํ๋ค. ์ด ๋ ๋งํฌ์
์ ๋ฌด์๋๊ธฐ ๋๋ฌธ์ ul.textContent = '<h1>Heading</h1>'
์ฒ๋ผ ๋งํฌ์
์ ํฌํจ์ํค๋ฉด ๋ฌธ์์ด๋ก ์ธ์๋์ด๊ทธ๋๋ก ์ถ๋ ฅ๋๋ค.
const ul = document.querySelector('ul');console.log(ul.textContent);
const cocker = document.getElementById('cocker');console.log(cocker.textContent);
cocker.textContent += '์ค ํ๋์';console.log(cocker.textContent);
cocker.textContent = '<li>์ฝ์นด์ค ํ๋์</li>';console.log(cocker.textContent);
#
innerTextinnerText ํ๋กํผํฐ๋ก๋ ํ ์คํธ ์ฝํ ์ธ ์ ์ ๊ทผํ ์ ์๋ค. ํ์ง๋ง ๋นํ์ค์ด๊ณ , CSS ์์ข ์ ์ด๋ผ, CSS์ ์ํด ๋นํ์ ๋์ด ์๋ ๊ฒฝ์ฐ ํ ์คํธ๊ฐ ๋ฐํ๋์ง ์๋๋ค. CSS๋ฅผ ๊ณ ๋ คํด์ผ ํ๊ธฐ ๋๋ฌธ์ textContent ํ๋กํผํฐ๋ณด๋ค ๋๋ฆฌ๋ค.
#
innerHTMLํด๋น ์์์ ๋ชจ๋ ์์ ์์๋ฅผ ํฌํจํ๋ ๋ชจ๋ ์ฝํ ์ธ ๋ฅผ ํ๋์ ๋ฌธ์์ด๋ก ์ทจ๋ํ ์ ์๋ค. ์ด ๋ฌธ์์ด์ ๋งํฌ์ ์ ํฌํจํ๋ค.
const ul = document.querySelector('ul');console.log(ul.innerHTML);
const cocker = document.getElementById('cocker');console.log(cocker.innerHTML);
cocker.innerHTML += '์ค ํ๋์';console.log(cocker.innerHTML);
cocker.innerHTML = '<li>์ฝ์นด์ค ํ๋์</li>';console.log(cocker.innerHTML);
innerHTML ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋งํฌ์ ์ด ํฌํจ๋ ์๋ก์ด ์์๋ฅผ DOM์ ์ถ๊ฐํ ์ ์๋ค .
const cocker = document.getElementById('cocker');cocker.innerHTML += '<li id="york" class="red">์ํฌ</li>';
ํ์ง๋ง ์ด๋ ๊ฒ ๋งํฌ์ ์ด ํฌํจ๋ ์ฝํ ์ธ ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ํฌ๋ก์ค ์คํฌ๋ฆฝํ ๊ณต๊ฒฉ์ ์ทจ์ฝํ๋ค
// ์๋ฌ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์์ผ ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋๋๋ก ํ๋ค.elem.innerHTML = '<img src="#" onerror="alert(\\'XSS\\')">';
#
DOM ์กฐ์ ๋ฐฉ์innerHTML ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์๋ก์ด ์ฝํ ์ธ ๋ฅผ ์ถ๊ฐํ ์ ์๋ ๋ฐฉ๋ฒ์ DOM์์ง์ ์กฐ์ํ๋ ๊ฒ์ด๋ค. ํ๋์ ์์๋ฅผ ์ถ๊ฐํ๋ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ค.
์์ ๋ ธ๋ ์์ฑ - createElement() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ์๋ก์ด ์์ ๋ ธ๋๋ฅผ ์์ฑํ๋ค. ๋ฉ์๋์ ์ธ์๋ก ํ๊ทธ ์ด๋ฆ์ ์ ๋ฌํ๋ค.
ํ ์คํธ ๋ ธ๋ ์์ฑ - createTextNode() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์๋ก์ด ํ ์คํธ ๋ ธ๋๋ฅผ ์์ฑํ๋ค. ๊ฒฝ์ฐ์ ๋ฐ๋ผ ์๋ตํ ์ ์์ง๋ง, ์๋ตํ๋ ๊ฒฝ์ฐ ์ฝํ ์ธ ๊ฐ ๋น์ด์๋ ์์๊ฐ๋๋ค.
์์ฑ๋ ์์๋ฅผ DOM์ ์ถ๊ฐ - appendChild() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑ๋ ๋ ธ๋๋ฅผ DOM tree์ ์ถ๊ฐํ๋ค. ๋๋ removeChild() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ DOM tree์์ ๋ ธ๋๋ฅผ ์ญ์ ํ ์๋ ์๋ค.
#
createElement(tagName)ํ๊ทธ ์ด๋ฆ์ ์ธ์๋ก ์ ๋ฌํ์ฌ ์์๋ฅผ ์์ฑํ๋ค.
Return : HTMLElement๋ฅผ ์์๋ฐ์ ๊ฐ์ฒด
#
createTextNode(text)ํ ์คํธ๋ฅผ ์ธ์๋ก ์ ๋ฌํ์ฌ ํ ์คํธ ๋ ธ๋๋ฅผ ์์ฑํ๋ค.
Return : Text ๊ฐ์ฒด
#
appendChild(Node)์ธ์๋ก ์ ๋ฌํ ๋ ธ๋๋ฅผ ๋ง์ง๋ง ์์ ์์๋ก DOM ํธ๋ฆฌ์ ์ถ๊ฐํ๋ค.
Return : ์ถ๊ฐํ ๋ ธ๋
#
removeChild(Node)์ธ์๋ก ์ ๋ฌํ ๋ ธ๋๋ฅผ DOM ํธ๋ฆฌ์ ์ ๊ฑฐํ๋ค.
Return : ์ ๊ฑฐํ ๋ ธ๋
// ํ๊ทธ ์ด๋ฆ์ ์ธ์๋ก ์ ๋ฌํ์ฌ ์๋ก์ด ์์ ์์ฑconst newDog = document.createElement('li');
// ํ
์คํธ ๋
ธ๋๋ฅผ ์์ฑconst newText = document.createTextNode('ํฌ๋ฉ๋ฆฌ์');
// ํ
์คํธ ๋
ธ๋๋ฅผ newDog์ ์์์ผ๋ก DOM ํธ๋ฆฌ์ ์ถ๊ฐnewDog.appendChild(newText);
const container = document.querySelector('ul');
// newElem์ container์ ์์์ผ๋ก DOM ํธ๋ฆฌ์ ์ถ๊ฐ. ๋ง์ง๋ง ์์๋ก ์ถ๊ฐ๋๋ค.container.appendChild(newDog);
const removeDog = document.getElementById('sichu');
// container์ ์์์ธ removeElem ์์๋ฅผ DOM ํธ๋ฆฌ์์ ์ ๊ฑฐํ๋คconsole.log(container.removeChild(removeDog));
#
insertAdjacentHTML(position, string)์ธ์๋ก ์ ๋ฌํ ํ ์คํธ๋ฅผ HTML๋ก ํ์ฑํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ก ์์ฑ๋ ๋ ธ๋๋ฅผ DOM ํธ๋ฆฌ์ ์ง์ ๋ ์์น์ ์ฝ์ ํ๋ค. ์ฒซ๋ฒ์งธ ์ธ์๋ ์ฝ์ ์์น, ๋๋ฒ์งธ ์ธ์๋ ์ฝ์ ํ ์์๋ฅผ ํํํ๋ฌธ์์ด์ด๋ค. ์ฒซ๋ฒ์งธ ์ธ์๋ก ์ฌ ์ ์๋ ๊ฐ์ ์๋์ ๊ฐ๋ค.
beforebegin
afterbegin
beforeend
afterend
<!-- beforebegin --><p> <!-- afterbegin --> foo <!-- beforeend --></p><!-- afterend -->
const dogList = document.querySelector('ul');dogList.insertAdjacentHTML('afterbegin', '<li id="york" class="dog">์ํฌ</li>');dogList.insertAdjacentHTML( 'beforeend', '<li id="dober" class="dog">๋๋ฒ ๋ฅด๋ง</li>',);
#
innerHTML vs DOM ์กฐ์ ๋ฐฉ์ vs insertAdjacentHTML()#
innerHTML์ฅ์ | ๋จ์ |
---|---|
DOM ์กฐ์ ๋ฐฉ์์ ๋นํด ๋น ๋ฅด๊ณ ๊ฐํธํ๋ค. | XSS๊ณต๊ฒฉ์ ์ทจ์ฝ์ ์ด ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๋ก ๋ถํฐ ์ ๋ ฅ๋ฐ์ ์ฝํ ์ธ (untrusted data: ๋๊ธ, ์ฌ์ฉ์ ์ด๋ฆ ๋ฑ)๋ฅผ ์ถ๊ฐํ ๋ ์ฃผ์ํ์ฌ์ผ ํ๋ค. |
๊ฐํธํ๊ฒ ๋ฌธ์์ด๋ก ์ ์ํ ์ฌ๋ฌ ์์๋ฅผ DOM์ ์ถ๊ฐํ ์ ์๋ค. | ํด๋น ์์์ ๋ด์ฉ์ ๋ฎ์ด ์ด๋ค. ์ฆ, HTML์ ๋ค์ ํ์ฑํ๋ค. ์ด๊ฒ์ ๋นํจ์จ์ ์ด๋ค. |
์ฝํ ์ธ ๋ฅผ ์ทจ๋ํ ์ ์๋ค. |
#
DOM ์กฐ์ ๋ฐฉ์์ฅ์ | ๋จ์ |
---|---|
ํน์ ๋ ธ๋ ํ ๊ฐ(๋ ธ๋, ํ ์คํธ, ๋ฐ์ดํฐ ๋ฑ)๋ฅผ DOM์ ์ถ๊ฐํ ๋ ์ ํฉํ๋ค. | innerHTML๋ณด๋ค ๋๋ฆฌ๊ณ ๋ ๋ง์ ์ฝ๋๊ฐ ํ์ํ๋ค. |
#
insertAdjacentHTML()์ฅ์ | ๋จ์ |
---|---|
๊ฐํธํ๊ฒ ๋ฌธ์์ด๋ก ์ ์๋ ์ฌ๋ฌ ์์๋ฅผ DOM์ ์ถ๊ฐํ ์ ์๋ค. | XSS๊ณต๊ฒฉ์ ์ทจ์ฝ์ ์ด ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๋ก ๋ถํฐ ์ ๋ ฅ๋ฐ์ ์ฝํ ์ธ (untrusted data: ๋๊ธ, ์ฌ์ฉ์ ์ด๋ฆ ๋ฑ)๋ฅผ ์ถ๊ฐํ ๋ ์ฃผ์ํ์ฌ์ผ ํ๋ค. |
์ฝ์ ๋๋ ์์น๋ฅผ ์ ์ ํ ์ ์๋ค. |
#
๊ฒฐ๋กinnerHTML๊ณผ insertAdjacentHTML()์ ํฌ๋ก์ค ์คํฌ๋ฆฝํ ๊ณต๊ฒฉ(XSS: Cross-Site Scripting Attacks)์ ์ทจ์ฝํ๋ค. ๋ฐ๋ผ์ untrusted data์ ๊ฒฝ์ฐ, ์ฃผ์ํ์ฌ์ผ ํ๋ค. ํ ์คํธ๋ฅผ ์ถ๊ฐ ๋๋ ๋ณ๊ฒฝ์์๋ textContent, ์๋ก์ด ์์์ ์ถ๊ฐ ๋๋ ์ญ์ ์์๋ DOM ์กฐ์ ๋ฐฉ์์ ์ฌ์ฉํ๋๋ก ํ๋ค.
#
stylestyle ์์ฑ์ ์ฌ์ฉํ๋ฉด inline ์คํ์ผ ์ ์ธ์ ์์ฑํ๋ค. ํน์ ์์์ inline ์คํ์ผ์์ง์ ํ๋ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ค.
const dogList = document.querySelector('ul');dogList.insertAdjacentHTML('afterbegin', '<li id="york" class="dog">์ํฌ</li>');dogList.insertAdjacentHTML( 'beforeend', '<li id="dober" class="dog">๋๋ฒ ๋ฅด๋ง</li>',);
const york = document.getElementById('york');const dober = document.getElementById('dober');
york.style.color = 'red';dober.style.color = 'red';
style ํ๋กํผํฐ ๊ฐ์ ์ทจ๋ํ๋ ค๋ฉด window.getComputedStyle์ ์ฌ์ฉํ๋ค. ์ด ๋ฉ์๋๋์ธ์๋ก ์ฃผ์ด์ง ์์์ ๋ชจ๋ CSS ํ๋กํผํฐ ๊ฐ์ ๋ฐํํ๋ค.
const box = document.querySelector('.box');
const width = getStyle(box, 'width');const height = getStyle(box, 'height');const backgroundColor = getStyle(box, 'background-color');const border = getStyle(box, 'border');
console.log('width: ' + width);console.log('height: ' + height);console.log('backgroundColor: ' + backgroundColor);console.log('border: ' + border);
/** * ์์์ ์ ์ฉ๋ CSS ํ๋กํผํฐ๋ฅผ ๋ฐํํ๋ค. * @param {HTTPElement} elem - ๋์ ์์ ๋
ธ๋. * @param {string} prop - ๋์ CSS ํ๋กํผํฐ. * @returns {string} CSS ํ๋กํผํฐ์ ๊ฐ. */function getStyle(elem, prop) { return window.getComputedStyle(elem, null).getPropertyValue(prop);}