요소 노드 취득
- HTML의 구조나 내용 또는 스타일 등을 동적으로 조작하려면 먼저 요소 노드를 취득해야 함
- 텍스트 노드는 요소 노드의 자식이고, 어트리뷰트 노드는 요소 노드와 연결되어 있기 때문
id를 이용한 요소 노드 취득
- Document.prototype.getElementById
- id값은 유일한 값이여야 하며 여러 개의 값을 가질 수 없음
- 첫 번째 요소 노드만 반환, 언제나 단 하나의 요소 노드를 반환
- 존재하지 않을 경우 null을 반환
- id 어트리뷰트를 부여하면 id 값과 동일한 이름의 전역 변수가 암묵적으로 선언되고, 해당 노드 객체가 할당됨
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="rive"></div>
</body>
<script>
console.log(rive === document.getElementById("rive")) //true
console.log(rive) //<div id="rive"></div>
</script>
</html>
태그 이름을 이용한 요소 노드 취득
- document.prototype/Element.prototype.getElementByTagName
- document vs element
- document → DOM의 루트 노드인 문서노드, 즉 document를 통해 호출, DOM 전체에서 요소 노드를 탐색하여 반환
- Element → 특정 요소 노드를 통해 호출, 특정 요소 노드의 자손 노드 중에서 요소 노드를 탐색하여 반환
- HTMLCollection 객체를 반환
- 모든 요소 노드를 취득하려면 인수로 * 전달
- 존재하지 않는 경우 빈 HTMLCollection 객체 반환
class를 이용한 요소 노드 취득
- document.prototype/Element.prototype.getElementByClassName
- 여러 개의 class를 지정할 수 있음
- HTMLCollection 객체를 반환
- 존재하지 않는 경우 빈 HTMLCollection 객체 반환
CSS 선택자를 이용한 요소 노드 취득
/* 전체 선택자: 모든 요소를 선택 */]
* { ... }
/* 태그 선택자: 모든 p 태그 요소를 모두 선택 */
p { ... }
/* id 선택자: id 값이 'foo'인 요소를 모두 선택 */
#foo { ... }
/* class 선택자: class 값이 'foo'인 요소를 모두 선택 */
foo { ... }
/* 어트리뷰트 선택자: input 요소 중에 type 어트리뷰트 값이 'text'인 요소를 모두 선택 */
input[type=text] { ... }
/* 후손 선택자: div 요소의 후손 요소 중 p 요소를 모두 선택 */
div p { ... }
/* 자식 선택자: div 요소의 자식 요소 중 p 요소를 모두 선택 */
div > p { ... }
/* 인접 형제 선택자: p 요소의 형제 요소 중에 p 요소 바로 뒤에 위치하는 ul 요소를 선택 */
p + ul { ... }
/* 일반 형제 선택자: p 요소의 형제 요소 중에 p 요소 뒤에 위치하는 ul 요소를 모두 선택 */
p ~ ul { ... }
/* 가상 클래스 선택자: hover 상태인 a 요소를 모두 선택 */
a:hover { ... }
/* 가상 요소 선택자: p 요소의 콘텐츠의 앞에 위치하는 공간을 선택
일반적으로 content 프로퍼티와 함께 사용된다. */
p::before { ... }
-알라딘 eBook <모던 자바스크립트 Deep Dive> (이웅모 지음) 중에서
- Document.prototype/Element.prototype.querySelector
- 여러 개 중 첫 번째 요소 노드만 봔환
- 존재하지 않는 경우 null 반환
- 문법에 맞지 않는 경우 DOMException 에러 발생
- Document.prototype/Element.prototype.querySelectorAll
- querySelector,querySelectorAll vs getElementByClassName, getElementById, getElementByTagName
- querySelector,querySelectorAll이 다소 느림
- 좀 더 구체적인 조건으로 요소 취득 가능함
- 일관된 방식으로 요소 취득 가능함
- 결론
- id → getElementById 메서드 사용
- 그 외 → querySelector,querySelectorAll 사용 권장
특정 요소 노드를 취득할 수 있는지 확인
- Element.prototype.matches
- 취득할 수 있는지 확인
- 이벤트 위임을 사용할 때 유용
HTMLCollection과 NodeList
- 공통점
- DOM API가 여러 개의 결과값을 반환하기 위한 DOM 컬렉션 객체
- 유사배열이면서 이터러블
- 차이점
- HTMLCollection
- 언제나 실시간으로 상태 변화를 반영하는 살아있는 객체
- for문으로 순회하면서 노드 객체의 상태를 변경해야 할 때 주의해야 함
- NodeList
- 과거의 정적 상태를 유지하는 non-live 객체로 동작
- 경우에 따라 live 객체로 동작할 때가 있음
- childNodes 프로퍼티가 반환하는 NodeList 객체는 HTMLCollection 객체처럼 실시간으로 노드 객체의 상태 변경을 반영하는 live 객체로 동작
- 결론
- 노드 객체의 상태 변경과 상관없이 안전하게 DOM 컬렉션을 사용하려면 HTMLCollection이나 NodeList 객체를 배열로 변환하여 사용하는 것을 권장
노드 탐색
- parentNode, previousSibling, firstChild, childNodes 프로퍼티는 Node.prototype이 제공
- previousElementSibling, nextElementSibling, child 프로퍼티는 Element.prototype이 제공
- 노드 탐색 프로퍼티는 참조만 가능한 읽기 전용 접근자 프로퍼티
공백 텍스트 노드
- 공백 문자는 공백 텍스트 노드를 생성
- 노드를 탐색할 때 공백 문자가 생성한 공백 텍스트 노드에 주의를 해야 함
자식 노드 존재 확인
- Node.prototype.hasChildNodes
- 텍스트 노드를 포함하여 자식 노드의 존재 확인
- child.length 또는 Element 인터페이스의 childElementCount 프로퍼티
요소 노드의 텍스트 조작
nodeValue
- Node.prototype.nodeValue
- 참조와 할당 모두 가능
- nodeValue프로퍼티를 참조하면 텍스트 노드의 텍스트 반환
- 텍스트 변경 가능
- 문서 노드나 요소 노드의 nodeValue 프로퍼티를 참조하면 null을 반환
textContent
- Node.prototype.textContent
- 요소 노드의 텍스트와 모든 자손 노드의 텍스트를 모두 취득하거나 변경
- textContent vs nodeValue
- nodeValue 가 코드가 더 복잡
- 결론
- 자식 요소 노드가 없고 텍스트만 존재할 경우 textContent 프로퍼티를 사용하는 편이 코드가 더 간단함
- innerText💩
- CSS에 의해 비표시로 지정된 요소 노드의 텍스트를 반환하지 않음
- textContent 프로퍼티보다 더 느림