본문 바로가기

JavaScript

[Deep dive] 39장 DOM (1)

DOM

- Document Object Mode

- HTML 문서의 계층적 구조와 정보를 표현하며 이를 제어할 수 있는 API , 즉 프로퍼티와 메서드를 제공하는 트리 자료구조 

 

39.1 노드 

 

39.1.1 HTML 요소와 노드 객체 

HTML 요소 

- HTML 문서를 구성하는 개별적인 요소 

- HTML 요소는 렌더링 엔진에 의해 파싱되어 DOM을 구성하는 요소 노드 객체로 변환

- HTML 문서는 HTML 요소들의 집합으로 이뤄지며, HTML 요소는 중첩 관계를 가짐

- HTML 요소 간의 부자 관계를 반영하여 HTML 문서의 구성 요소인 HTML 요소를 객체화한 모든 노드 객체들을 트리 자료구조로 구성

트리 자료구조 

- 부모 노드(parent node)와 자식 노드 (child node)로 구성되어 노드 간의 계층적 구조를 표현하는 비선형 자료구조 

- 최상위 노드 = 루트 노드이며 루트노드는 0개 이상의 자식노드를 가짐

- 리프 토드 = 자식 노드가 없는 노드 

- DOM = 노드 객체들로 구성된 트리 자료구조 

 

39.1.2 노드 객체의 타입

- 노드 객체는 종류가 있고 상속구조를 가짐

- 노드 객체는 총 12개의 종류가 있음

 

1) 문서 노드 (document node)

- DOM 트리의 최상위에 존재하는 루트 노드로서  document 객체를 가리킴

- document 객체는 브라우저가 렌더링한 HTML 문서 전체를 가라키는 객체로서 전역 객체 window의 document 프로퍼티에 바인딩되어 있음

- 브라우저 환경의 모든 자바스크립트 코드는 script 태그에 의해 분리되어 있어도 하나의 전역 객체 window를 공유 

( HTML 문서당 document 객체는 유일)

 

2) 요소 노드(element node)

-  HTML 요소를 가리키는 객체 

- HTML 요소 간의 중첩에 의해 부자 관계를 가지며, 이 부자 관계를 통해 정보를 구조화 

- 요소 노드는 문서의 구조를 표현

 

3) 어트리뷰트 노드 (attribute node)

- HTML 요소의 어트리뷰트를 가리키는 객체 

- 어트리뷰트 노드는 부모노드가 없으므로 형제(silibing)노드가 아님

- 어트리뷰트 노드에 접근하여 어트리뷰트를 참조하거나 변경하려면 먼저 요소 노드에 접근해야 함

 

4) 텍스트 노드 (Text node)

- HTML 요소의 텍스트를 가리키는 객체 

- 문서의 정보를 표현

- 요소노드의 자식 노드이며 리프노드 

 

39.1.3 노드 객체의 상속 구조 

- DOM을 구성하는 노드 객체는 브라우저 환경에서 추가적으로 제공하는 호스트 객체 (host object)

- 노드 객체도 자바스크립트 객체이므로 프로토타입에 의한 상속 구조를 가짐

- 모든 노드 객체는 Object, EventTarget, Node 인터페이스를 상속 받음

- 요소 노드는 Element 인터페이스를 상속받음 

 

- 프로토 체인 관점 

ex) input 요소를 파싱하여 객체화한 input 요소 노드 객체는 HTMLInputElement, HTMLElement, Element, Node, EventTarget, Object의 prototype에 바인딩되어 있는 프로토타입 객체를 상속 받음

input 요소 노드 객체의 특성 프로토타입을 제공하는 객체
객체 Object
이벤트를 발생시키는 객체 EventTarget
트리 자료구조의 노드 객체 Node
브라우저가 렌더링할 수 있는 웹 문서의 요소(HTML,XML,SVG)을 표현하는 객체  Element
웹 문서 요소 중에서 HTML 요소를 표현하는 객체  HTMLEIement
HTML 요소 중에서 input 요소를 표현하는 객체  HTMLInputElement

- 노드 객체는 공통된 기능일수록 프로토타입 체인의 상위에, 개별적인 고유 기능일수록 프로토타입 체인의 하위에 프로토타입 체인을 구축하여 노드 객체에 필요한 기능, 즉 프로퍼티와 메서드를 제공하는 상속 구조를 가짐

 

- DOM은 HTML 문서의 계층적 구조와 정보를 표현하는 것은 물론 노드 객체의 종류, 즉 노드 타입에 따라 필요한 기능을 프로퍼티와 메서드의 집합인 DOM API로 제공. 이 DOM API를 통해 HTML의 구조나 내용 또는 스타일 등을 동적으로 조작할 수 있음

 

39.2 요소 노드 취득

 

- HTML의 구조나 내용 또는 스타일 등을 동적으로 조작하려면 먼저 요소 노드를 취득해야 함

 

39.2.1 id를 이용한 요소 노드 취득

- Document.prototype.getElementById 메서드는 인수로 전달한 id 어트리뷰트 값을 갖는 하나의 요소를 탐색하여 반환 

- Document.prototype의 프로퍼티이므로 문서 노드인 document를 통해 호출해야 함

- 중복된 id값을 갖는 요소가 여러개 존재한다면 첫 번째 요소 노드만 반환 

- 인수로 전달된 id 값을 갖는 HTML 요소가 존재하지 않는다면 null을 반환

<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <ul>
      <li id="apple"> Apple</li>
      <li id="banana">Banana</li>
      <li id="orange">Orange</li>
    </ul>
    <script>
      //id 값이 'banana'인 요소 노드를 탐색하여 반환
      //두 번째 li 요소가 파싱되어 생성된 요소 노드가 반환
      const $elem = document.getElementById('banana');

      //취득한 요소 노드의 style.color프로퍼티 값을 변경
      $elem.style.color = 'red';
    </script>
  </body>
</html>

- HTML 요소에 id 어트리뷰트를 부여하면 id 값과 동일한 이름의 전역 변수가 암묵적으로 선언되고 해당 노드 객체가 할당되는 부수 효과 존재

- id 값과 동일한 이름의 전역 변수가 이미 선언되어 있으면 이 전역 변수에 노드 객체가 재할당되지 않음

<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <div id = "foo"></div>
    <script>
    //id값과 동일한 이름의 전역 변수가 암묵적으로 선언되고 해당 노드 객체가 할당
    console.log(foo === document.getElementById('foo')); //true

    //암묵적 전역으로 생성된 전역 프로퍼티는 삭제되지만 전역 변수는 삭제되지 않음
    delete foo;
    console.log(foo); //<div id="foo"></div>
    </script>
  </body>
</html>

 

39.2.2 태그 이름을 이용한 요소 노드 취득

- Document.prototype/Element.prototype.getElementByTagName 메서드는 인수로 전달한 태그 이름을 갖는 모든 요소 노드들을 탐색하여 반환 

- 여러 개의 노드 객체를 갖는 DOM 컬렉션 객체인 HTMLCollection 객체를 반환

- HTMLCollection 객체는 유사 배열 객체이면서 이터러블 

<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <ul>
      <li id="apple">Apple</li>
      <li id="banana">Banana</li>
      <li id="orange">Orange</li>
    </ul>
    <script>
      //태그 이름이 li인 요소 노드를 모두 탐색하여 반환
      //탐색된 요소 노드들은 HTMLCollection 객체에 담겨 반환
      //HTMLCollection 객체는 유사 배열 객체이면서 이터러블
      const $elems = document.getElementsByTagName('li');

      //취득한 모든 요소 노드의 style.color 프로퍼티 값을 변경
      //HTMLCollection 객체를 배열로 변환하여 순회하며 color 값을 변경
      [...$elems].forEach(elem => {elem.style.color='red'};);
    </script>
  </body>
</html>

- HTML 문서의 모든 요소 노드를 취득하려면 getElementByTagNames 메서드의 인수로 '*'를 전달

//모든 요소 노드를 탐색하여 반환
const $all = document.getElementByTagName('*');
Document.prototype.getElementsByTagName document를 통해 호출하며 DOM 전체에서 요소 노드를 탐색하여 반환
Element.prototype.getElementsByTagName 특정 요소 노드를 통해 호출하며, 특정 요소 노드의 자손 노드 중에서 요소 노드를 탐색하여 반환 

 

39.2.3 class를 이용한 요소 노드 취득 

- Documet.prototype/Element.prototype.getElementsByClassName 메서드는 인수로 전달한 class 어트리뷰트 값을 갖는 모든 요소들을 탐색하여 반환 

- 여러 개의 요소 노드 객체를 갖는 DOM 컬렉션 객체인 HTMLColleciton 객체를 반환 

<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <ul>
      <li id="fruit apple">Apple</li>
      <li id="fruit banana">Banana</li>
      <li id="fruit orange">Orange</li>
    </ul>
    <script>
      //class 값이 'fruit'인 요소 노드를 모두 탐색하여 HTMLCollection 객체에 담아 반환
      const $elems = document.getElementsByClassName('fruit');

      //취득한 모든 요소의 CSS color 프로퍼티 값을 변경
      [...$elems].forEach(elem => {elem.style.color = 'red';});

      //class 값이 'fruit apple'인 요소 노드를 모두 탐색하여 HTMLCollection 객체에 담아 반환 
      const $apples = document.getElementsByClassName('fruit apple');

      //취득한 모든 요소의 style.color 프로퍼티 값을 변경
      [...$apples].forEach(elem => {elem.style.color = 'blue';});
    </script>
  </body>
</html>
Document.prototype.getElementsByClassName document를 통해 호출하며 DOM 전체에서 요소 노드를 탐색하여 반환
Element.prototype.getElementsByClassName 특정 요소 노드를 통해 호출하며 특정 요소 노드의 자손 노드 중에서 요소 노드를 탐색하여 반환 

 

39.2.4 CSS 선택자를 이용한 요소 노드 취득

-CSS 선택자는 스타일을 적용하고자 하는 HTML 요소를 특정할 때 사용하는 문법

 

//전체 선택자 : 모든 요소를 선택 
* {...}
//태그 선택자 : 모든 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 {...}

- Document.prototype/Element.prototype.querySelector 메서드는 인수로 전달한 CSS 선택자를 만족시키는 하나의 요소를 탐색하여 반환

- 인수로 전달한 CSS 선택자를 만족시키는 요소 노드가 여러 개인 경우 첫 번째 요소 노드만 반환

- 인수로 전달된 CSS 선택자를 만족시키는 요소 노드가 존재하지 않는 경우 null을 반환

- 인수로 전달한 CSS 선택자가 문법에 맞지 않는 경우 DOMException 에러 발생

 

<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <ul>
      <li id="fruit apple">Apple</li>
      <li id="fruit banana">Banana</li>
      <li id="fruit orange">Orange</li>
    </ul>
    <script>
      // class 어트리뷰트 값이 'banana'인 첫 번째 요소 노드를 탐색하여 반환
      const $elem = document.querySelector('.banana');
      //취득한 요소 노드의 style.color 프로퍼티 값을 변경
      $elem.style.color ='red';
    </script>
  </body>
</html>

- querySelectorAll 메서드는 인수로 전달한 CSS 선택자를 만족시키는 모든 요소 노드를 탐색하여 반환

- 여러 개의 요소 노드 객체를 갖는 DOM 컬렉션 객체인 NodeList 객체를 반환

<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <ul>
      <li id="fruit apple">Apple</li>
      <li id="fruit banana">Banana</li>
      <li id="fruit orange">Orange</li>
    </ul>
    <script>
     //ul 요소의 자식 요소인 li 요소를 모두 탐색하여 반환
     const $elems = document.querySelectorAll('ul>li');
     //취득한 요소 노드들은 NodeList 객체에 담겨 반환
     console.log($elems); //NodeList(3) [li.apple,li.banana,li.orange]

     //취득한 모든 요소 노드의 style.color 프로퍼티 값을 변경
     //NodeList는 forEach 메서드를 제공
     $elems.forEach(elem => {elem.style.color = 'red';});
    </script>
  </body>
</html>
Document.prototype.querySelector document를 통해 호출하며 DOM 전체에서 요소 노드를 탐색하여 반환
Element.prototype.querySelector 특정 요소 노드를 통해 호출하며 특정 요소 노드의 자손 노드 중에서 요소노드를 탐색하여 반환 

 

39.2.5 특정 요소 노드를 취득할 수 있는지 확인

- Element.prototype.matches 메서드는 인수로 전달한 CSS 선택자를 통해 특정 요소 노드를 취득할 수 있는지 확인

- 이벤트 위임을 사용할 떄 유용

<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <ul>
      <li id="fruit apple">Apple</li>
      <li id="fruit banana">Banana</li>
      <li id="fruit orange">Orange</li>
    </ul>
    <script>
     const $apple = document.querySelector('.apple');

     //$apple 노드는 '#fruits > li.apple'로 취득 할 수 있다
     console.log($apple.mathches('#fruits > li.apple'));
     //$apple 노드는 '#fruits > li.banana'로 취득 할 수 없다
     console.log($apple.matches('#fruits>li.banana'));
    </script>
  </body>
</html>

 

39.2.6 HTMLCollection과 NodeList

- HTMLCollection과 NodeList는 DOM API가 여러 개의 결과값을 반환하기 위한 DOM 컬렉션 객체 

- 모두 유사 배열 객체이면서 이터러블

- 노드 객체 상태 변화를 실시간으로 반영하는 살아있는(live) 객체

- HTMLColleciton은 언제나 live 객체로 동작

- NodeLIst는 대부분의 경우 노드 객체의 상태 변활르 실시간으로 반영하지 않고 과거의 정적 상태를 유지하는 non-live 객체로 동작하지만 경우에 따라 live 객체로 동작할 때가 있음

 

1) HTMLCollection

- 노드 객체의 상태 변화를 실시간으로 반영하는 살아 있는(live) DOM 컬렉션 객체 

- 실시간으로 노드 객체의 상태 변경을 반영하여 요소를 제거할 수 있기 때문에 HTMLCollection 객체를 for문으로 순회하면서 노드 객체의 상태를 변경해야 할 때는 주의 해야함

 

2) NodeList

- 실시간으로 노드 객체의 상태 변경을 반영하지 않는 (non-live) 객체

- But, ChildNodes 프로퍼티가 반환하는 NodeList 객체는 실시간으로 노드 객체의 상태 변경을 반영하는 live 객체로 동작 

<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <ul id="fruits">
      <li>Apple</li>
      <li>Banana</li>
    </ul>
    <script>
     const $fruits = document.getElementById('fruits');

     //childNodes 프로퍼티는 NodeList 객체(live)를 반환
     const { childNodes } = $fruits;
     console.log(childNodes instanceof NodeList); //true

     //$fruits 요소의 자식 노드는 공백 텍스트 노드를 포함해 5개 
     console.log(childNodes); //NodeList(5) [text,li,text,li,text]

     for(let i = 0; i < childNodes.length; i++) {
      //removeChild 메서드가 호출될 떄마다 NodeList 객체인 childNodes가 실시간으로 변경
      //따라서 첫 번쨰, 세 번째, 다섯 번째 요소만 삭제 
      $fruits.removeChild(childNodes[i]);
     }

     //예상과 다르게 $fruits 요소의 모든 자식 노드가 삭제되지 않음
     console.log(childNodes); //NodeList(2) [li,li]
    </script>
  </body>
</html>

- 노드 객체의 상태 변경과 상관없이 안전하게 DOM 컬렉션을 사용하려면 HTMLCollection이나 NodeList 객체를 배열로 변환하여 사용하는 것을 권장

 

39.3 노드 탐색

 

- DOM 트리 상위 노드를 탐색할 수 있도록 Node, Element 인터페이스는 트리 탐색 프로퍼티를 제공\

- 노드 탐색 프로퍼티는 setter 없이 getter만 존재하여 참조만 가능한 읽기 전용 프로퍼티 

Node.prototype이 제공 prarentNode, previousSibling, firstChild, childNodes 프로퍼티
Element.prototype이 제공 previousElementSibling, nextElementSibling, children 프로퍼티 

 

39.3.1 공백 텍스트 노드 

- HTML 요소 사이의 스페이스, 탭, 줄바꿈(개행) 등의 공백(white space)문자는 텍스트 노드를 생성

 

39.3.2 자식 노드 탐색

프로퍼티 설명
Node.prototype.childNodes - 자식 노드를 모두 탐색하여 DOM 컬렉션 객체인 NodeList에 담아 반환
- childNodes 프로퍼티가 반환한 NodeList에는 요소 노드 쭌만아니라 텍스트 노드도 포함되어 있을 수 있음
Element.prototype.children - 자식 노드 중에서 요소 노드만 모두 탐색하여 DOM 컬렉션 객체인 HTMLCollection에 담아 반환 
- children 프로퍼티가 반한한 HTMLCollection에는 텍스트 노드가 포함되지 않는다
Node.prototype.firstChild - 첫 번째 자식 노드를 반환
- firstChild 프로퍼티가 반환한 노드는 텍스트 노드이거나 요소 노드 
Node.prototype.lastChild - 마지막 자식 노드를 반환
- lastChild 프로퍼티가 반환한 노드는 텍스트 노드이거나 요소 노드 
Element.prototype.firstElementChild - 첫 번째 자식 노드를 반환
- firstElementChild 프로퍼티는 요소 노드만 반환
Element.prototype.lastElementChild - 마지막 자식 노드를 반환
- lastElementChild 프로퍼터는 요소 노드만 반환
<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <ul id="fruits">
      <li class = "apple">Apple</li>
      <li clsss = "banana">Banana</li>
      <li class = "orange">Orange</li>  
    </ul>
    <script>
      //노드 탐색의 기점이 되는 #fruis 요소 노드를 취득
      const $fruits = document.getElementById('fruits');

      console.log($fruits.childNodes);
      //NodeList(7) [text, li.apple, text, li.banana, text, li.orante, text]

      console.log($fruits.children);
      //HTMLCollection(3) [li.apple, li.banana, li.orange]

      console.log($fruits.fristChild);
      //#text

      console.log($fruits.lastChild);
      //#text

      console.log($fruits.firstElementChild); 
      //li.apple

      console.log($fruits.lastElementChild);
      //li.orange
    </script>
  </body>
</html>


39.3.3 자식 노드 존재 확인

- Node.prototype.hasChildNodes 메서드를 사용하여 자식 노드가 존재하는지 확인

- 자식 노드가 존재하면 true, 자식 노드가 존재하지 않으면 false를 반환 

- 택스트 노드를 포함하여 자식노드의 존재 확인 

<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <ul id="fruits">
    </ul>
    <script>
      //노드 탐색의 기점이 되는 #fruits 요소 노드를 취득 
      const $fruits = document.getElementById('fruits');

      //hasChildNodes 메서드는 텍스트 노드를 포함하여 자식 노드의 존재를 확인
      console.log($fruits.hasChildNodes()); //ture
    </script>
  </body>
</html>

- 자식 노드 중에 텍스트 노드가 아닌 요소 노드가 존재하는지 확인하려면 children.length 또는 Element 인터페이스의 childElementCount 프로퍼티를 사용

conosle.log(!!$fruits.children.length); //false
console.log(!!$fruits.childElementCount); //false

 

39.3.4 요소 노드의 텍스트 노드 탐색

- 요소 노드의 텍스트 노드는 요소 노드의 자식 노드 

- 요소 노드의 텍스트 노드는 firstChild 프로퍼티로 접근 가능 

<div id = "foo">Hello</div>
<script>
    //요소 노드의 텍스트 노드는 firstChild 프로퍼티로 접근할 수 있다
    console.log(document.getElementById('foo').fristChild); //#text
</script>

 

39.3.5 부모 노드 탐색

- Node.prototype.parentNode 프로퍼티를 사용하여 부모 노드 탐색

- 텍스트 노드는 리프 노드이므로 부모 노드가 텍스트 노드인 경우는 없음

<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <ul id="fruits">
      <li class = "apple">Apple</li>
      <li class = "banana">Banana</li>
      <li class = "orange">Orange</li>
    </ul>
    <script>
      //노드 탐색의 기점이 되는 .banana 요소 노드를 취득한다
      const $banana = document.querySelector('.banana');

      //.banana 요소 노드의 부모 노드를 탐색
      console.log($banana.parentNode); //ul#fruits
    </script>
  </body>
</html>

 

39.3.6 형제 노드 탐색

- 어트리뷰트 노드는 요소 노드와 연결되어 있지만 부모 노드가 같은 형제 노드가 아니므로 반환되지 않음

- 텍스트 노드 또는 요소 노드만 반환

프로퍼티 설명
Node.prototype.previousSibling - 부모 노드가 같은 형제 노드 중에서 자신의 이전 형제 노드를 탐색하여 반환 
- 요소 노드 + 텍스트 노드
Node.prototype.nextSibling - 부모 노드가 같은 형제 노드 중에서 자신의 다음 형제 노드를 탐색하여 반환
- 요소 노드  + 텍스트 노드
Element.prototype.previousElementSibling - 부모 노드가 같은 형제 노드 중에서 자신의 이전 형제 요소 노드를 탐색하여 반환 
- 요소 노드만
Element.prototype.nextElementSibling - 부모 노드가 같은 형제 노드 중에서 자신의 다음 형제 노드를 탐색하여 반환
- 요소 노드만
<!DOCTYPE html>
<html>
  <head>
    <meta charset = "UTF-8">
    <link rel="stlyesheet" href = "style.css">
  </head>
  <body>
    <ul id="fruits">
      <li class = "apple">Apple</li>
      <li class = "banana">Banana</li>
      <li class = "orange">Orange</li>
    </ul>
    <script>
      //노드 탐색의 기점이 되는 #fruits 요소 노드를 취득
      const $fruits = document.getElementById('fruits');

      const {firstChild } = $fruits;
      console.log(firstChild); //#text

      const {nextSibling} = firstChild;
      console.log(nextSibling); //li.apple

      const {previousSibling} = nextSibling;
      console.log(previousSibling); //#text

      const {firstElementChild} = $fruits;
      console.log(firstElementChild); //li.apple

      const {nextElementSibling} = firstElementChild;
      console.log(nextElementSibling); //li.banana

      const{previousElementSibling} = nextElementSibling;
      console.log(previousElementSibling); //li.apple

    </script>
  </body>
</html>

'JavaScript' 카테고리의 다른 글

[Deep dive] 39장 DOM (3)  (0) 2023.08.21
[Deep dive] 39장 DOM (2)  (0) 2023.08.21
[Deep dive] 38장 브라우저의 렌더링 과정  (0) 2023.08.18
[Deep dive] 37장 Set과 Map  (0) 2023.08.18
[Deep dive] 36장 디스트럭처링 할당  (0) 2023.08.18