출처 : https://javascript.info/modifying-document
DOM변경의 key는 live page를 생성이다. 어떻게 새로운 element를 생성하고 존재하는 page content를 수정하는지 알아보자.
Example: show a message
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<div class="alert">
<strong>Hi there!</strong> You've read an important message.
</div>
JavaScript로 동일한 div를 만들어보자.
Creating an element
DOM nodes를 만드는 데 2가지 함수가 있다.
let div = document.createElement('div');
// 주어진 tag로 새로운 element node를 생성한다.
let textNode = document.createTextNode('Here I am');
//주어진 text로 새로운 text node를 생성한다.
대부분의 경우 우리는 element node를 생성한다.
Creating the message
message div를 만드는 데 3steps이 있다.
// 1. Create <div> element
let div = document.createElement('div');
// 2. Set its class to "alert"
div.className = "alert";
// 3. Fill it with the content
div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
이제 element를 만들었다. 하지만 div라는 변수에만 있고, page에는 없다.
Insertion methods
div가 보여지기 위해서, document안의 어딘가에 추가를 해야한다.
document.body.append(div)
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<script>
let div = document.createElement('div');
div.className = "alert";
div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
document.body.append(div);
</script>
insertion methods
- node.append(...nodes or strings) - node 끝에 추가한다.
- node.prepend(...nodes or strings) - node 앞에 추가한다.
- node.before(...nodes or strings) - node 전에 추가한다.
- node.after(...nodes or strings) - node 위에 추가한다.
- node.replaceWith(...nodes or strings) - node를 교체한다.
<ol id="ol">
<li>0</li>
<li>1</li>
<li>2</li>
</ol>
<script>
ol.before('before'); // insert string "before" before <ol>
ol.after('after'); // insert string "after" after <ol>
let liFirst = document.createElement('li');
liFirst.innerHTML = 'prepend';
ol.prepend(liFirst); // insert liFirst at the beginning of <ol>
let liLast = document.createElement('li');
liLast.innerHTML = 'append';
ol.append(liLast); // insert liLast at the end of <ol>
</script>
output :
before
- prepend
- 0
- 1
- 2
- append
after
최종 html은 이렇게 된다.
before
<ol id="ol">
<li>prepend</li>
<li>0</li>
<li>1</li>
<li>2</li>
<li>append</li>
</ol>
after
text는 HTML이 아닌 text로 추가되며, <, >와 같은 문자는 escaping된다.
elem.textContent처럼 문자열을 안전하게 추가할 수 있다.
<div id="div"></div>
<script>
div.before('<p>Hello</p>', document.createElement('hr'));
</script>
output :
<p>Hello</p>
<hr>
<div id="div"></div>
만약에, elem.innerHTML처럼 HTML string을 html로 추가하고 싶은 경우에는 어떻게 할까?
insertAdjacentHTML/Text/Element
elem.insertAdjacentHTML(where, html)함수가 꽤 유용하다.
첫번째 parameter는 다음 중 하나가 된다.
- beforebegin
- afterbegin
- beforeend
- afterend
두번째 parameter는 HTML string이며, HTML로 추가된다.
<div id="div"></div>
<script>
div.insertAdjacentHTML('beforebegin', '<p>Hello</p>');
div.insertAdjacentHTML('afterend', '<p>Bye</p>');
</script>
OUTPUT :
<p>Hello</p>
<div id="div"></div>
<p>Bye</p>
유사한 함수가 2가지 더 있다. 하지만 주로 append/prepend/before/after를 사용한다.
- elem.insertAdjacentText(where, text)
- elem.insertAdjacentElement(where, text)
Node 삭제
node를 삭제하기 위해서 node.remove()함수를 사용한다.
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<script>
let div = document.createElement('div');
div.className = "alert";
div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
document.body.append(div);
setTimeout(() => div.remove(), 1000);
</script>
element위치를 옮기고 싶다면 삭제할 필요가 없다.
모든 insertion method는 자동적으로 old place에서 node를 삭제시킨다.
<div id="first">First</div>
<div id="second">Second</div>
<script>
// no need to call remove
second.after(first); // take #second and after it insert #first
</script>
Cloning nodes: cloneNode
어떻게 하나 이상의 유사한 메시지를 추가할 수 있을까?
함수를 만들 수 있지만, 기존 div를 clone하고, 내부 text를 수정하는 방법도 있다.
big element를 복사해야 한다면, 후자가 더 빠르고 간단하다.
elem.cloneNode(true) : deep clone, 모든 attributes와 subelements 포함
elem.cloneNode(false) : child elements 제외
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<div class="alert" id="div">
<strong>Hi there!</strong> You've read an important message.
</div>
<script>
let div2 = div.cloneNode(true); // clone the message
div2.querySelector('strong').innerHTML = 'Bye there!'; // change the clone
div.after(div2); // show the clone after the existing div
</script>
DocumentFragment
DocumentFragment는 node lists를 감싸는 wrapper와 같은 DOM node이다.
다른 node를 append할 수 있고, 어딘가 insert를 할때 content가 insert된다.
<ul id="ul"></ul>
<script>
function getListContent() {
let fragment = new DocumentFragment();
for(let i=1; i<=3; i++) {
let li = document.createElement('li');
li.append(i);
fragment.append(li);
}
return fragment;
}
ul.append(getListContent()); // (*)
</script>
OUTPUT :
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
DocumentFragment는 드물게 사용된다. DocumentFragment 대신에, node arrray를 반환할 수 있다.
<ul id="ul"></ul>
<script>
function getListContent() {
let result = [];
for(let i=1; i<=3; i++) {
let li = document.createElement('li');
li.append(i);
result.push(li);
}
return result;
}
ul.append(...getListContent()); // append + "..." operator = friends!
</script>
Old-school insert/remove methods
- parentElem.appendChild(node)
- parentElem.insertBefore(node, nextSibling)
- parentElem.replaceChild(node, oldChild)
- parentElem.removeChild(node)
과거 script를 이해하기위한 정보이지, 해당 함수를 개발 시 사용하지는 않는다.
A word about “document.write”
web-page에 뭔가 추가하기 위한 원시적인 함수가 있다.
document.write
<p>Somewhere in the page...</p>
<script>
document.write('<b>Hello from JS</b>');
</script>
<p>The end</p>
document.write(html)은 html을 page에 그 자리에 바로 추가한다. 오래된 함수로 아직 동작하지만, 기능이 제한적이다. document.write 함수는 오직 page 로딩 시에만 동작한다. 로딩 이후에 호출하면 기존재하는 document content는 삭제된다.
<p>After one second the contents of this page will be replaced...</p>
<script>
// document.write after 1 second
// that's after the page loaded, so it erases the existing content
setTimeout(() => document.write('<b>...By this.</b>'), 1000);
</script>
따라서, 로딩된 이후 단계에서는 사용불가하다. 하지만, document.write함수는 빠르다. 많은양의 HTML을 dynamically하게 추가하기 위해서는 유용하다.
Summary
- Methods to create new nodes:
- document.createElement(tag) – creates an element with the given tag,
- document.createTextNode(value) – creates a text node (rarely used),
- elem.cloneNode(deep) – clones the element, if deep==true then with all descendants.
- Insertion and removal:
- node.append(...nodes or strings) – insert into node, at the end,
- node.prepend(...nodes or strings) – insert into node, at the beginning,
- node.before(...nodes or strings) –- insert right before node,
- node.after(...nodes or strings) –- insert right after node,
- node.replaceWith(...nodes or strings) –- replace node.
- node.remove() –- remove the node.
- There are also “old school” methods:
- parent.appendChild(node)
- parent.insertBefore(node, nextSibling)
- parent.removeChild(node)
- parent.replaceChild(newElem, node)
- Given some HTML in html, elem.insertAdjacentHTML(where, html) inserts it depending on the value of where:
- "beforebegin" – insert html right before elem,
- "afterbegin" – insert html into elem, at the beginning,
- "beforeend" – insert html into elem, at the end,
- "afterend" – insert html right after elem.
- To append HTML to the page before it has finished loading:
- document.write(html)
'JavaScript' 카테고리의 다른 글
JavaScript] Window sizes and scrolling (0) | 2022.11.14 |
---|---|
JavaScript] Document Styles and classes (1) | 2022.11.14 |
JavaScript] HTML attributes and DOM properties (0) | 2022.11.08 |
JavaScript] DOM Node properties (0) | 2022.11.04 |
JavaScript] Searching: getElement*, querySelector* (0) | 2022.11.04 |
댓글