문서 객체 모델(DOM)
HTML에 접근하기 위한 모델(인터페이스)이며, HTML을 컨트롤하기 위한 방법 그 자체를 기술한 것이다.
문서 내의 모든 요소를 정의하고, 각각의 요소에 접근하는 방법을 제공한다.
우리는 이 DOM으로 모든 HTML요소 및 속성, CSS스타일을 변경할 수 있으며, 이벤트를 추가하고, 이벤트에 반응할 수 있다.
DOM은 W3C의 표준 객체 모델이다.
DOM에 접근해 보자
문서가 로드될 때(모든 DOM을 사용할 수 있게 되는 때) 실행되는 함수를 정의하였다. 새로운 H1 element를 생성하고, element에 text를 추가하며, H1을 이 문서의 트리에 추가한다.
<html>
<head>
<script>
// run this function when the document is loaded
window.onload = function() {
// create a couple of elements in an otherwise empty HTML page
var heading = document.createElement("h1");
var heading_text = document.createTextNode("Big Head!");
heading.appendChild(heading_text);
document.body.appendChild(heading);
}
</script>
</head>
<body>
</body>
</html>
브라우저는 HTML문서를 로드한 후 해당 문서에 대한 모델을 메모리에 생성한다.
이 때 생성된 객체들의 구조를 DOMTREE라 부른다.
DOM Tree와 네 가지 노드
DOM의 모든 요소들은 document 객체의 자식이며, 모든 요소들, 어트리뷰트, 텍스트는 하나의 객체이다.
문서노드
트리 최상단에 위치해있으며, 모든 요소 노드에 접근하기 위해서는 문서노드를 거쳐가야 한다.
요소노드
HTML요소 자체를 표현하며, 문서의 구조를 서술한다.
중첩에 의해 부모자식관계를 가지며, 이 관계를 통해 정보를 구조화한다.
모든 요소노드는 요소별 특성을 표현하기 위해 HTMLElement 객체를 상속한 객체로 구성된다.
어트리뷰트노드
HTML요소의 속성을 표현한다.
해당 속성이 지정된 요소의 자식이 아니라 해당 요소의 일부(형제)로 표현된다.
해당 요소노드를 찾아 접근하게 되면, 속성을 참조 및 수정이 가능해진다.
텍스트노드
HTML요소의 텍스트를 표현하는 최하단노드이다.
DOM 사용하기
DOM Query를 사용하기 위해 기본적으로 document 개체가 필요하다.
getElementById('id')
id속성값으로 요소노드를 한 개 선택한다.
만약 복수개가 선택되면 가장 마지막 요소를 선택한다.
<ul>
<li id="one" class="red1">썬타워503호</li>
<li id="two" class="red1">썬타워502호</li>
<li id="three" class="red1">썬타워501호</li>
<li id="four">서울</li>
</ul>
<script>
document.getElementById('one').style.backgroundColor='yellow';
console.dir(document.getElementById('one'));
</script>
console.dir을 통해 해당 요소의 노드구조를 파악할 수 있으며, 어떤 프로퍼티에 어떻게 접근해야하는지 확인할 수 있다.
이를 통해 자유자재로 돔을 이동하는 것을 트래버싱(Traversing)이라 한다.
querySelector
요소노드를 1개 선택하는 document 객체의 메서드
만약 여러개가 선택이 되면 첫 번째 요소만 선택되며, querySelectorAll을 사용하여 전체를 선택할 수 있다.
// ID는 #, class는 .을 사용해야 한다.
document.querySelector('#one').style.backgroundColor='yellow';
getElementByClassName
클래스를 통한 노드의 선택
document.getElementByClassName('red1').style.backgroundColor='yellow';
노드 탐색
firstChild, lastChild
공백이나 줄바꿈 문자를 텍스트노드 취급하기 때문에, 공백제거 시 가독성이 나빠지는 태그에서는
firstElementchild, lastElementChild를 사용할 것을 권장한다.
<ul>
<li id="one" class="red1">서울</li>
<li id="two" class="red1">부산</li>
<li id="three" class="red1">제주</li>
<li id="four">경기</li>
</ul>
<script>
console.log(document.querySelector('ul').firstChild); // #text
</script>
//<ul>과 <li>사이의 공백을 다 제거하고 난 후 실행하면 <li>값을 가져온다.
hasChildNodes()
자식노드 확인 후 Boolean값을 리턴한다.
const tf = document.querySelector('ul');
console.log(tf.hasChildNodes()); // true
childNodes
자식노드의 컬렉션(텍스트를 포함한 모든 자식요소)을 리턴한다.
console.log(tf.childNodes);
// NodeList(9) [text, li#one.red1, text, li#two.red1, text, li#three.red1, text, li#four, text]
children
자식노드의 컬렉션(Element타입)을 리턴한다.
console.log(tf.children);
// HTMLCollection(4) [li#one.red1, li#two.red1, li#three.red1, li#four, one: li#one.red1, two: li#two.red1, three: li#three.red1, four: li#four]
previousSibling, nextSibling
형제(이웃)노드를 탐색한다. (텍스트노드 포함)
console.log(tf.previousSibling); // #text
console.log(tf.nextSibling); // #text
perviousElementSibling, nextElementSibling
형제(이웃)노드를 탐색한다. (텍스트노드 미포함)
console.log(tf.previousElementSibling); // h1
console.log(tf.nextElementSibling); // h2#quiz
nodeName, nodeType, nodeValue
노드 탐색
nodeValue의 값 : 1(요소 노드) 2(속성 노드) 3(텍스트 노드) 8(주석 노드) 9(문서 노드)
console.log(tf.nodeName);
console.log(tf.nodeType);
console.log(tf.nodeValue);
className
class 속성값 취득 및 변경
className 프로퍼티에 값을 할당하는 경우 class가 존재하지 않으면 속성을 생성하고 값을 지정한다.
class 속성값이 여러개라면 공백으로 구분된 문자열이 리턴되므로 split을 활용하여 배열로 변경해 사용한다.
classList
DOMTokenList를 반환하는 읽기 전용 프로퍼티
- 메서드 종류 : add, remove, item, toggle, contains, replace 등
See the Pen Untitled by magic (@mag11c) on CodePen.
어트리뷰트 관련 속성
hasAttribute
지정한 어트리뷰트를 가지고 있는지
getAttribute
어트리뷰트의 값을 취득
setAttribute
지정한 어트리뷰트의 값을 설정
removeAttribute
지정한 어트리뷰트 제거
<input type="text">
<script>
const input = document.querySelector('input[type=text]');
console.log(input);
//value 어트리뷰트 값이 없다면
if(!input.hasAttribute('value')){
input.setAttribute('placeholder', '값을 입력해주세요');
}
// focus로 인풋안에 들어왔는지 확인.
// value값 가져오기
console.log(input.getAttribute('value'));
//value 제거
input.removeAttribute('value');
</script>
텍스트 변경
innerHTML
요소의 텍스트에 접근할 수 있는 프로퍼티
innerText
해당 요소의 모든 자식요소를 포함하는 모든 컨텐츠를 하나의 문자열로 가져올 수 있다.
W3C에표준에 맞지않고, css에 순종적이라 css속성에따라 받아올 수 없으며, textContent대비 느려 비사용 권장
textContent
요소의 텍스트 컨텐츠를 취득 및 변경한다.
textContent를 통해 요소에 새로운 텍스트를 할당하면 텍스트를 쉽게 변경 가능하다.
<ul>
<li id="one" class="red1">서울</li>
<li id="two" class="red1">부산</li>
<li id="three" class="red1">제주</li>
<li id="four">경기</li>
</ul>
<script>
one.textContent = '<h1>22</h1>';
console.log(one.textContent); // <h1>22</h1>;
// 마크업 적용
one.innerHTML += '<h1>22</h1>';
one.innerHTML += '<img src ="경로">';
</script>
컨텐츠 추가
createElement
메서드의 파라미터로 태그명을 만들어 반환한다.
createTextNode
텍스트노드를 생성한다.
appendChild
한 노드를 특정 부모노드의 자식리스트 중 마지막 자식으로 붙인다.
removeChild
파라미터로 전달받은 자식노드를 삭제한다.
<ul>
<li id="one" class="red1">서울</li>
<li id="two" class="red1">부산</li>
<li id="three" class="red1">제주</li>
<li id="four">경기</li>
</ul>
<script>
const newEl = document.createElement('li');
const newText = document.createTextNode('오우쨔스');
newEl.appendChild(newText);
const container = document.querySelector('ul');
container.appendChild(newEl);
container.removeChild(document.querySelector('#two'));
</script>
'부산'이 삭제되고 '오우쨔스'가 추가되었다.
참조
https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model
2023.04 ~ 백엔드 개발자의 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!