참고서적: DOM - 잡았다, 요 돔!, DOM 을 깨우치다
DOM 을 보니 좀더 깊이 공부해야할것으로 느껴졌다. 아마 앞의 진도에서는 자바스크립트를 배우며 DOM 역시 같이 사용할 것이다. 더 깊숙히 공부하기 위해 해당 내용을 정리하며, 공부하도록 하자.
본 내용은 공부할 목적으로 적은 내용이므로, 틀린 내용이 포함될 수 있다.
DOM 은 HTML 문서를 자바스크립트로 사용할 수 있도록 객체화시킨후, 구조화 시킨 것이다.
그래서 Documnet Object Model 이라고 부른다.
이러한 DOM은 HTML 이 어떠한 과정으로 렌더링이 이루어지는지 아는 것이 중요하다.
웹 브라우저는 자신만의 엔진 (Chrome 같은 경우 V8 Engine) 으로, 작성된 HTML, CSS, Javascript 문서를 읽어 화면에 출력한다.
이때 HTML, CSS 를 사용하여 문서를 분석하는데, 이러한 분석을 Pasring 이라한다.
과정은 대략 이러하다.
아래의 단계는 내가 이해하고 있는 단계이다.
내부 로직을 분석해서 알고 있는것이 아니며 추상적으로 이해하고 있기에 틀릴 수 있는 내용이 포함될수 있는점 참고 바란다.
DOM Tree 란 HTML 을 parsing 하여 HTML tag 상의 연관관계를 Tree 구조로 해석하는 방식을 말한다.
자세한것은 JAVASCRIPT.INFO 의 DOM 트리 에서 자세히 설명되어 있다.
CSS Rules 는 HTML 의 특정한 element 를 어떻게 렌더링 할지 알려주는 CSS 문장이라고 보면 된다.
Parsing 된 Tree 는 내부적으로 attach method 를 포함하고 있다.
이렇게 포함된 attach method 를 Attachment 단계에서 호출하여 DOM Tree 의 정보를 담은 객체로 만든다.
Render Tree 는 앞서서 이야기한 CSS Rules 와 DOM Tree 의 각 정보를 병합하여 하나의 객체를 만들어 Tree 형식으로 구조화시킨것을 말한다.
보통 문서가 만들어진 이후, Javascript 를 이용하여 Layout 이 변경된다면 이 단계까지 실행된다. 이렇게 Layout 이 변경되는 작업이 이루어질때 보통
reFlow
되었다 이야기 한다.
문서가 만들어진 이후, 스타일이 변경된다면 Painting 작업단계까지 실행된다. 이렇게 Painting 작업이 변경될때 보통
rePaint
되었다 이야기 한다.
이렇게 화면이 출력되는 각 단계가 존재한다.
여기서 DOM 은 이러한 객체정보를 가진 Element 를 생성, 수정, 삭제, 읽기(CRUD)를 할 수 있도록 Javascript 객체로 만들어진 것이라고 생각한다.
즉 HTML 을 조작할 수 있도록 만들어진 API 이다.
Node 는 DOM 에서 사용하는 용어로, 객체화 시킨 요소를 뜻한다.
만약 다음의 HTML 이 있다고 생각하자
<html lang="en">
<head>
<title>text</title>
</head>
<body>
</body>
</html>
이때 아래처럼 Node 가 만들어진다.
[ document ]
|
[ html ]
|
---------------
| |
[ head ] [ body ]
|
---
|
[ title ]
|
text
이러한 Tree 구조에서 만들어진 이후, 각 구조의 요소를 Node 라고 생각하면된다.
마치 가계관계도 같이 생겼는데 이러한 관계도를 Tree 구조라 한다.
이때 각 Node 를 표현하는 용어가 몇가지 있다.
자식이 없는 Node
종단점
중간 노드
모든 노드들의 부모노드
시작점
이러한 용어는 원할한 소통을 위해 알아두는것이 좋을 듯 싶다.
그렇다면 Node 의 종류를 알아보자
여기서 말하는 nodeType 은 각 type 을 나타내는 숫자값이라고 생각하면 된다.
숫자값은 워낙에 추상적이라, Node 객체에 내장되어 있는 해당 Node 타입값을 가진 프로퍼티도 같이 제공한다.
nodeType: 9
Node.DOCUMENT_NODEDocument Node 는 HTML 의 최상위 문서이다. 이는 위에 말한 Root Node 라고 생각하면 된다. 문서에 대한 전역적 접근이 필요할때 사용가능하다.
nodeType: 2
Node.ATTRIBUTE_NODE
DOM Level 4 에서는 deprecated 되었다 한다.
HTML 속성을 나타내는 Node 이다.
nodeType: 3
Node.TEXT_NODEHTML의 모든 문자 및 공백을 말한다.
nodeType: 8
Node.COMMENT_NODE문서상의 주석을 나타내는 Node 이다.
nodeType: 1
Node.ELEMENT_NODEHTML의 각 요소를 말한다고 보면 된다. div, span, input, etc... 같은 모든 요소를 뜻한다.
위의 노드타입은 노드 식별을 쉽게 알아보기 위해 숫자값으로 제공하는 방식이다.
만약 HTML 상에 testElem
이라는 id
를 가진 div element
가 있다고 가정한다
let elem = document.getElementById("testElem");
console.log(elem.nodeType === 1); // true
if (elem.nodeType === 1) { // true
console.log("엘리먼트이에요"); // 출력
}
이렇게 숫자값으로 출력도 가능한데, 외우기 어렵다면 다음처럼 사용해도 된다.
const elem = document.getElementById("testElem");
console.log(elem.nodeType === Node.ELEMENT_NODE); // true
if (elem.nodeType === Node.ELEMENT_NODE) { // true
console.log("엘리먼트이에요"); // 출력
}
BOM 은 DOM 과는 다르게 Browser Object Model 을 뜻한다.
이는 브라우저 환경을 객체로 제공하여 변경 가능하도록 만들어진 객체 모델이라고 생각하면 된다.
DOM 구조에 접근하기 위해서는 Root Node 에 접근하여 Node 를 가져와야 한다.
여기서 list3
을 가진 li
를 가져와 보자!!
document.querySelectorAll()
을 말그대로 지정자를 query 하는 메소드이다.
여기에 All 이 붙었으니 해당 메소드를 사용하면, 해당 태그를 전부 가져온다.
해당 태그만 가져오면 되지 태그를 전부 가져오는가?
해당 태그를 가져오기 위해서는
식별할수 있는 식별자
가 있어야 한다.
ex)class
,id
같은
하지만 식별자가 없을때는 관련된 태그를 전부다 가져와야 한다.
(태그는 배열형식(NodeList
)으로 저장된다. 이는NodeList
에 대해 알아야 한다.NodeList
은 밑에 바로 설명한다.)
가져온 태그들중 원하는 태그를 가져오는 방식을 사용해 본다.
다음을 보자.
NodeList
여기서 중요한 점은
NodeList
는 배열이 아니라는점이다.
객체로 이루어져 있으며 마치 배열처럼 동작하는ArrayLikeObject
이다.
다음을 보자.let elems = document.querySelectorAll("li"); // html 상의 모든 li 를 가져온다. // 이때 elems 는 배열같이 생긴 객체로 되어 있다. { '0': li, '1': li, '2': li, '3': li, 'length': 4 }
마치 객체로 이루어진 배열 같다.
이러한 객체를ArrayLikeObject
라 부른다.
여기서 중요한 것은NodeList
는 배열이 아니지만, 배열처럼 동작한다는것이다.
실제 배열이 아니기에filter
,map
,reduce
같은배열의 method
는 사용할 수 없다.
하지만 편의상forEach
는 제공하는듯 하다.
IE
에서는forEach
미지원
NodeList
는 마치 배열처럼 생긴 객체로 이해하자.
이용하기도 편하다 문자열 값으로 CSS 선택자방식을 사용하여 해당 태그 지정이 가능하다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div class="list">
<ul>
<li>list1</li>
<li>list2</li>
<li>list3</li>
<li>list4</li>
</ul>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elems = document.querySelectorAll(".list li");
console.log(elems);// // NodeList[li, li, li, li]
const list3 = elems[2];
console.log(list3); // <li>list3</li>
만약 단일 태그을 가져오고 싶다면 document.querySelector()
를 사용하여 태그를 가져온다. 이 querySelector
는 태그 한개만을 가져온다는는 것을 명심하자.
만약,
querySelector
를 사용하였는데, 태그가 1개 보다 더 많으면, 해당 태그 목록중 가장 상위의 태그 한개를 반환한다.
querySelector
는 보통 식별가능한 식별자가 있을때 많이 사용한다.
아래의 예제는 class active
식별자를 통해서 해당 요소를 가져와 본다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div class="list">
<ul>
<li>list1</li>
<li class="active">list2</li>
<li>list3</li>
<li>list4</li>
</ul>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elem = document.querySelector(".active");
console.log(elem); // li.active
이는 css 선택자 문법을 사용해서 쉽게 해당 요소를 가져올수 있지만, 각 선택자에 따른 다른 메서드들 역시 존재한다.
document.getElementById
는document
상의ID selector
를 사용하여 해당Element
를 가져온다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li>list1</li>
<li>list2</li>
<li>list3</li>
<li class="active">list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elem = document.getElementById("wrapper");
console.log(elem); // div#wrapper
이는 document
상에 유일한 식별자인 ID
를 사용하므로, getElements
가 아닌 getElement
로 쓴다는것을 명확히 알아두는 것이 좋다.
처음 사용할때 자주 실수하는 부분이다.
document.getElementsByTagName
은document
상의tag
이름을 식별한다.tag
는 한개가 아닌 여러개일 가능성이 많으므로, 해당 메소드는 항상 유사객체(ArrayLike) 형식으로 반환한다.중요한것은
querySelectorAll
과는 다르게NodeList
가 아닌HTMLCollection
객체를 반환한다.실상,
NodeList
와HTMLCollection
은 서로 다르면서 비슷한 면이 많다.
이에 대해서는 추후 시간이 되면 다른 파트에서 설명한다.
HTMLCollection
은실시간 변경
으로 인해 예상치 못한 결과가 발생할 수 있다. 그리므로 꼭Array
로 변환하여 사용하자.
Array.from
및spread opreator
을 사용하여Array
로 만들어 사용하길 권장한다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li>list1</li>
<li>list2</li>
<li>list3</li>
<li class="active">list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elems = document.getElementsByTag("li");
console.log(elems); // HTMLCollection[li, li, li, li.active]
// if 배열로 만든다면 다음과 같다.
const ElemstoArr1 = [...elems]; // or
const ElemstoArr2 = Array.from(elems);
사용시 단수가 아닌 복수이므로 getElementsBy
로 해야 한다.
document.getElementsByClassName
는 말그대로class
식별자를 사용하여 값을 가진다.
알다시피,class
는id
와 달리 복수지정이 가능하다. 그러므로getElementsBy
로 시작한다.
document.getElementsByClassName
역시HTMLCollection
을 반환한다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li>list1</li>
<li class="even">list2</li>
<li>list3</li>
<li class="even">list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elems = document.getElementsByClassName("even");
console.log(elems); // HTMLCollection[li.even, li.even]
만약
Node
만 선택했다면 무쓸모일것이다.
매번Node
를 선택해서 사용하는것은 불편하다.
쓸모있게 만들려면 해당 선택한Node
를 기점으로 다른 노드를 찾을 수 있어야 한다.
DOM
은 이러한Navigation
능력도 있다.
document
내의 노드를 훨씬 빠르게 찾을 수 있어서 자바스크립트 최적화에 도움을 줍니다.
DOM - 잡았다, 요 돔!
요소를 탐색해보자.
Element.parentNode
는 해당Node
의 부모노드를 찾는다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li>list1</li>
<li class="even">list2</li>
<li>list3</li>
<li class="even">list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elem = document.querySelector(".even");
// .even 을 가진 li중 가장 첫번째 li 를 가져온다
console.log(elem.parentNode); // ul
Element.firstChild
는Node
의 자식중 첫번째Node
를 가져온다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li class="firstChild">list1</li>
<li>list2</li>
<li>list3</li>
<li>list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elem = document.querySelector(".list ul"); // ul
console.log(elem.firstChild); //#text
이거 상황이 이상하다.
.list ul
의 자식이면 li.firstChild
가 나와야 하는데 #text
가 나왔다!!
DOM
은 실제 HTML Documnent
상의 공백 텍스트
역시 하나의 Node
로 인식한다.
Node.TEXT_NODE
가 Text Node
이다.
공백역시 Text Node
로 인식한다.
이는 띄어쓰기 및 줄바꿈도 포함된다.
위의 상황은 다음과 같다
<!DOCTYPE html>
<html lang="ko"><!-- 공백 텍스트 -->
<head><!-- 공백 텍스트 -->
<title>Document</title><!-- 공백 텍스트 -->
</head><!-- 공백 텍스트 -->
<body><!-- 공백 텍스트 -->
<div id="wrapper"><!-- 공백 텍스트 -->
<div class="list"><!-- 공백 텍스트 -->
<ul><!-- 공백 텍스트 -->
<li class="firstChild">list1</li><!-- 공백 텍스트 -->
<li>list2</li><!-- 공백 텍스트 -->
<li>list3</li><!-- 공백 텍스트 -->
<li>list4</li><!-- 공백 텍스트 -->
</ul><!-- 공백 텍스트 -->
</div><!-- 공백 텍스트 -->
</div><!-- 공백 텍스트 -->
<script src="./script/index.js"></script><!-- 공백 텍스트 -->
</body><!-- 공백 텍스트 -->
</html><!-- 공백 텍스트 -->
ul
부분만 보자면 다음과 같다.
<ul><!-- 공백 텍스트 -->
<li class="firstChild">list1</li><!-- 공백 텍스트 -->
<li>list2</li><!-- 공백 텍스트 -->
<li>list3</li><!-- 공백 텍스트 -->
<li>list4</li><!-- 공백 텍스트 -->
</ul><!-- 공백 텍스트 -->
여기서 ul
의 firstChild
는 즉 ul
옆의 공백 택스트
이다.
이러한 텍스트 노드를 chrome devTool
에서는 #text
로 나온다.
그럼 li.firstChild
를 선택하려면, 두번째 자식을 선택해야 한다.
이때 nextSibilng
을 사용한다.
nextSibling 은 선택한
Node
의 다음Node
를 선택한다.앞의 firstChild 에서
#text(공백 텍스트)
가 나왔다.
원하는Element
는ul
다음의 첫번째li
이다.firstChild
에서 이어서 다음 요소를 탐색해 본다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li class="firstChild">list1</li>
<li>list2</li>
<li>list3</li>
<li>list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elem = document.querySelector(".list ul");
console.log(elem.firstChild.nextSibling); // li.firstChild
이번에는 원하는 li.firstChild
가 나온것을 알 수 있다.
firstChild
가 있다면lastChild
도 있을 것이다.
lastChild
는 마지막Node
를 선택한다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li>list1</li>
<li>list2</li>
<li>list3</li>
<li class="lastChild">list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elem = document.querySelector(".list ul");
console.log(elem.lastChild); // #text
역시 이번에도 #text(공백 문자)
가 나왔다.
이는 앞에서 설명한 대로 Text Node
역시 하나의 Node
로 인식하기에 생겨난 현상이다.
앞에서는 nextSibling
을 썼지만, 이번에는 Next
가 아닌 Previous
이다.
previsousSibling
은 해당Node
의 앞Node
를 선택한다.
위의 내용에서previousSibling
을 사용해본다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li>list1</li>
<li>list2</li>
<li>list3</li>
<li class="lastchild">list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elem = document.querySelector(".list ul");
console.log(elem.lastChild.previousSibling); // <li>list4</li>
정상적으로 <li>list4</li>
가 나오는것을 확인할 수 있다.
일반적으로 위의 명령어들 firstChild
, lastChild
, nextSibling
, previousSibling
들은 전부 method
가 아닌property
임을 명심하자.
위의 속성들은 전부 Node
객체의 property
이다.
Node
객체의 property
는 다음의 테이블과 같다.
name | description |
---|---|
childNodes | 자식 노드를 전부 반환한다. 반환요소는 NodeList 이다. |
firstChild | 자식 노드중 첫번째 자식 노드를 반환한다. |
lastChild | 자식 노드중 마지막 자식 노드를 반환한다. |
nextSibling | 선택된 노드에서 다음 노드를 선택한다. |
previousSibling | 선택된 노드에서 이전 노드를 선택한다. |
nodeName | 선택된 노드의 노드 이름을 반환한다. |
nodeValue | 선택된 노드타입이 Node.TEXT_NODE , Node.COMMNET_NODE 일때만 반환한다. 그 이외의 노드타입은 전부 null 값을 반환한다. |
nodeType | 선택된 노드의 노드 타입을 반환한다 |
parentNode | 선택된 노드의 부모 노드를 반환한다. |
위의 테이블중 다른것은 쉽게 이해가 가는데 nodeValue
부분이 걸린다.
nodeValue
를 좀더 살펴보자.
다음은 앞전의 previousSibling
의 내용을 그대로 가져왔다.
선택된 li.lastChild
에 nodeValue
프로퍼티를 가져와 본다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li>list1</li>
<li>list2</li>
<li>list3</li>
<li class="lastchild">list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elem = document.querySelector(".list ul");
console.log(elem.lastChild.previousSibling.nodeValue); // null
null
이 나온다.
위의 테이블에서 nodeValue
의 내용은 다음과 같다
선택된 노드타입이
Node.TEXT_NODE
,Node.COMMNET_NODE
일때만 반환한다.
그 이외의 노드타입은 전부null
값을 반환한다.
위 말은 선택된 노드의 타입이 TEXT_NODE
및 COMMENT_NODE
이어야 한다.
하지만 위의 elem.lastChild.previousSibling
은 노드 타입이 Node.ELEMENT_NODE
이다.
노드 타입을 확인하기 위해 nodeType
속성을 사용해 본다.
nodeType
은 선택된 노드의 노드 타입을 반환한다
다음 script
로 확인해보자.
// script/index.js
const elem = document.querySelector(".list ul");
console.log(elem.lastChild.previousSibling.nodeType === Node.ELEMENT_NODE); // true
값은 true
가 나온다.
즉 elem.lastChild.previousSibling
의 노드 타입은 Node.ELEMENT_NODE
로 확인되었다.
그렇다면 li.lastChild
안의 list4
텍스트를 선택하여 nodeValue
속성을 사용하면 값을 반환하지 않을까?
const elem = document.querySelector(".list ul");
console.log(elem.lastChild.previousSibling.firstChild.nodeValue); // list4
이번에는 제대로 값이 반환되는것을 확인 할 수 있다.
nodeValue
는 문자관련 노드에서만 값을 반환하는것을 알게 되었다.
지금까지 Node
관련 속성에 대해서 알아보았다.
사실 Node
로 탐색하는것은 매우 불편한 일이다.
앞에서 보았듯이 empty text
도 하나의 Node
로 취급하기 때문이다.
그래서 Node
가 아닌 HTMLElement
내부에 다른 property
들이 존재한다.
HTMLElement
메서드들은 정말 HTMLElement
만 탐색 가능하기에 훨씬 편하게 사용 가능하다.
HTML*Element 는 무엇인가?
HTML 문서 내의 각 element 들은 고유한 성질을 가지며, 각자 element 를 DOM 트리 내의 노드 개체로 인스턴스화하는 고유한
javascript
생성자를 가진다. 예를 들어,<a>
는HTMLAnchorElement
생성자를 통해 DOM 노드로 만들어진다.출처: DOM 을 깨우치다
HTMLElement
는 각 객체로 인스턴스화 시키는 생성자가 있다고 말하고 있다. 이러한 생성자를 통해 내부 속성 및 메서드가 만들어진다. 다음은 이러한 생성자를 확인할 수 있는 링크이다.
해당 링크에서Interface
를 보면 각HTML*Element
의 생성자를 알 수 있다.여기서
HTML*Element
의*
은 해당Element
의 이름이다.참조링크: HTML*Element 전체목록
나중에 Typescript 공부할 때, DOM Type 에 대한 이해에 유용할 듯 싶다.
Node
는 객체이며,Node
를 조작하기 위해 여러가지Sub Object
를 가진다.
Element
는Node
의Sub Object
이다.
또한HTMLElement
는Element
의Sub Object
이다.
Node
의document
역시Sub Object
중 하나이다.
HTML*Element
를 다루기 위해,Node
의Sub Object
중 하나인Element
객체의 속성을 사용하여 내용을 탐색해 본다.
document
객체와Element
의 중요한 차이점이 존재한다.document
는HTML document
상Root Node
인HTMLdocument
를 직접 참조하여 속성을 사용하지만,
Element
는 선택한HTMLElement
에서HTML*Element
를 참조하여 속성을 사용한다.
즉, 모든HTML*Element
는HTMLElement
의 자식이며,Element
의 자손이다.
이제부터 사용하는 속성들은 이러한Element
의 속성을 사용한다.깊게 들어가면 어렵다ㅠㅠ, 굳이 이해하지 않아도 속성은 구현되어 있으니 그냥 사용하면 된다.
Element.firstElementChild
는Element
의 자식중 첫번째Element
를 가져온다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li class="firstChild">list1</li>
<li>list2</li>
<li>list3</li>
<li>list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elem = document.querySelector(".list ul"); // ul
console.log(elem.firstElementChild); // li.firstChild
앞에서의 TEXT_NODE
가 아닌 Element
를 가져온다.
원하는 Element
를 쉽게 가져올 수 있어서 더 유용하게 사용가능하겠다.
lastElementChild
는 마지막Element
를 반환한다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li>list1</li>
<li>list2</li>
<li>list3</li>
<li class="lastChild">list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elem = document.querySelector(".list ul");
console.log(elem.lastElementChild); // li.lastChild
nextElementChild 는 선택한
Element
의 다음Element
를 선택한다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>Document</title>
</head>
<body>
<div id="wrapper">
<div class="list">
<ul>
<li class="previousChild">list1</li>
<li class="nextChild">list2</li>
<li>list3</li>
<li>list4</li>
</ul>
</div>
</div>
<script src="./script/index.js"></script>
</body>
</html>
// script/index.js
const elem = document.querySelector(".list ul");
console.log(elem.firstChild.nextElementChild); // li.nextElemetChild
원하는 li.nextElementChild
가 나온것을 알 수 있다.
이번에는 해당 요소의 이전 li
인 li.previouseChild
를 탐색해보자.
// script/index.js
const elem = document.querySelector(".list ul");
const nextChild = elem.firstChild.nextElementChild; // li.nextChild
console.log(nextChild.prevousElementChild); // li.previousChild
Node
탐색과는 다르게 쉽게 원하는 Element
를 탐색한다.
다음은 Element
에서 제공하는 탐색 관련 속성들의 테이블이다.
name | description |
---|---|
childern | 자식 요소를 전부 반환한다. 반환요소는 HTMLCollection 이다. |
firstElementChild | 자식 요소중 첫번째 자식 요소를 반환한다. |
lastElementChild | 자식 요소중 마지막 자식 요소를 반환한다. |
nextElementChild | 선택된 요소에서 다음 요소를 선택한다. |
previousElementChild | 선택된 요소에서 이전 요소를 선택한다. |
이상으로 DOM 탐색 및 선택에 대해 알아보았다.
다음은 생성 및 추가에 대해서 알아본다.