김 양의 멋따라 개발따기

39.2 요소 노드 취득~39.5 요소 노드의 텍스트 조작 본문

모던 자바스크립트 Deep Dive

39.2 요소 노드 취득~39.5 요소 노드의 텍스트 조작

개발따라김양 2023. 1. 26. 08:57

요소 노드 취득

  • 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
    • NodeList 객체를 반환
      • 유사배열이면서 이터러블
  • 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 프로퍼티보다 더 느림

'모던 자바스크립트 Deep Dive' 카테고리의 다른 글

39-1 노드  (0) 2023.01.25
38장 브라우저의 렌더링 과정  (1) 2023.01.24