[javascript] DOM

Mandy·2022년 9월 25일
0
post-thumbnail

안녕하세요! 이번 포스팅에서는 DOM의 개념과 특징에 대해 알아보는 시간을 가져볼까 합니다.

DOM



DOM 이란 무엇일까요?

문서 객체 모델(Document Object Model)
: 문서의 구조화된 표현(structured representation)을 제공하며 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 프로그래밍 언어가 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕습니다. DOM 은 nodes와 objects로 문서를 표현합니다.
또한, DOM은 HTML, ECMAScript에서 정의한 표준이 아닌 별개의 W3C의 공식 표준이며 플랫폼/프로그래밍 언어 중립적입니다.


javascript로 문서 구조를 변경하면 발생하는 일.gif

여기서 프로그래밍 언어란, 웹 프론트엔드 개발에서 대개 javascript를 의미합니다.
다만, DOM의 구현은 어떠한 언어에서도 가능하기 때문에 파이썬 등의 다른 언어로도 사용합니다.

javascript로 HTML, CSS로 작성한 요소에 접근하여 속성이나 내용등을 변경할 수 있게 되는것입니다!


DOM의 종류

W3C DOM 표준은 세 가지 모델로 구분됩니다.

  1. Core DOM : 모든 문서 타입을 위한 DOM 모델

Core DOM 최초 객체 모델이 완성된 1988년 부터 HTML과 XML등을 다루기 위해서 생겨났습니다. 이후 HTML DOM과 XML DOM등이 추가 되었지만 Core DOM은 웹 브라우저간의 호환성이 뛰어나서 주로 사용됩니다.

  1. HTML DOM : HTML 문서를 위한 DOM 모델

HTML 태그에 대한 기본 모델로 id를 사용해 객체 모델을 작성합니다. Core DOM 에 비해 단순한 구조를 가지고 있지만 웹브라우저마다 지원이 안될수가 있어 호환성에 문제가 생길 수 있습니다.
HTML DOM은 HTML 문서를 조작하고 접근하는 표준화된 방법을 정의하며, 모든 HTML 요소는 HTML DOM를 통해 접근할 수 있습니다.

  1. XML DOM : XML 문서를 위한 DOM 모델

XML DOM은 XML 문서에 접근하여, 그 문서를 다루는 표준화된 방법을 정의합니다.
모든 XML 요소는 XML DOM를 통해 접근할 수 있습니다. DOM을 사용하여 XML 문서를 프로그래밍 방식으로 읽고, 조작하고, 수정할 수 있습니다.



Document 객체



document는 DOM 트리의 최상위 객체이며, window 객체의 하위객체입니다. window.document 으로 접근할 수 있습니다.
브라우저는 HTML 문서를 로드하기 전에 document 객체를 먼저 만듭니다.
document 객체를 뿌리로 하는 DOM 트리를 만들기 때문에
웹 페이지에 존재하는 HTML 요소에 처음 접근하고자 할 때는 Document 객체부터 시작해야 합니다.



Document 객체의 역할

  • 프로퍼티로 HTML 문서의 전반적 속성을 나타냄

  • 메소드로 DOM 객체 검색

  • 메소드로 새로운 DOM 객체 생성

  • 메소드로 HTML 문서의 전반적 제어 지원




Document 메소드


Document 객체는 HTML 요소와 관련된 작업을 도와주는 다양한 메소드를 제공합니다.

  • HTML 요소의 선택

  • HTML 요소의 생성

  • HTML 이벤트 핸들러 추가

  • HTML 객체의 선택



DOM 요소의 선택

HTML 요소를 다루기 위해서는 우선 해당 요소를 선택해야만 합니다.
자바스크립트에서 특정 HTML 요소를 선택하는 방법은 다음과 같습니다.


특정 변수에 요소를 할당한 상태가 아니라면 태그, 클래스, 아이디 이름에 ' '(작은 따옴표)나 " "(큰 따옴표)로 감싸서 작성합니다.



[1. HTML 태그 이름(tag name)을 이용한 선택 ]


getElementsByTagName() 메소드는 HTML 태그 이름을 이용하여 HTML 요소를 선택합니다.
루트 노드를 포함해 전체 Document를 대상으로 검색됩니다.
name 은 엘리먼트의 이름을 나타내는 문자열입니다. name에 "*" 를 기입하면 모든 엘리먼트를 나타냅니다.
태그 name 파라미터에 일치하는 모든 자손 엘리먼트의 집합을 생성합니다.

var elements = document.getElementsByTagName(name);



[2. 아이디(id)를 이용한 선택 ]


getElementById() 메소드는 아이디를 이용하여 HTML 요소를 선택합니다.
주어진 문자열과 일치하는 id 속성을 가진 요소를 찾고, 이를 나타내는 Element 객체를 반환합니다.
ID는 문서 내에서 유일해야 하기 때문에 특정 요소를 빠르게 찾을 때 유용합니다.

var element = document.getElementById(id);



[3. 클래스(class)를 이용한 선택 ]


**getElementsByClassName()** 메소드는 클래스 이름을 이용하여 HTML 요소를 선택합니다. **주어진 클래스를 가진 모든 자식 엘리먼트**의 실시간 HTMLCollection 을 반환합니다. ``` var elements = document.getElementsByClassName(names); ```



[4. name 속성(attribute)을 이용한 선택 ]


getElementsByName() 메소드는 HTML 요소의 name 속성을 이용하여 HTML 요소를 선택합니다.
주어진 이름 속성을 가진 요소의 NodeList 컬렉션을 반환합니다.

var elements = document.getElementsByName(name)



[5. CSS 선택자(selector)를 이용한 선택 ]


**querySelector()** 메소드는 CSS 선택자(아이디, 클래스, 속성, 속성값 등)를 이용하여 HTML 요소를 선택합니다. 제공한 선택자 또는 선택자 뭉치와 일치하는 문서 내 첫 번째 Element를 반환합니다. 일치하는 요소가 없으면 null을 반환합니다. ``` var element = document.querySelector(selectors); ```

💨**특수 문자 이스케이프**
CSS 구문을 따르지 않는, 예컨대 콜론이나 공백을 포함한 선택자나 ID를 사용해야 하면 **반드시 백슬래시("\")를 사용해 해당 문자를 이스케이프해야 합니다. ** 백슬래시는 JavaScript의 이스케이프 문자이기 때문에, 백슬래시를 문자로 입력하려면 반드시 두 번 입력해야 합니다.
<div id="foo\bar"></div>
<div id="foo:bar"></div>

<script>
  document.querySelector('#foo\\bar') // 첫 번째 <div>
  document.querySelector('#foo\\:bar') // 두 번째 <div>
</script>



💭좀 더 복잡한 선택자
태그, 클래스, 아이디, 네임, 속성값 등을 나열하여 더욱 자세한 선택자 사용이 가능합니다.
아래 코드처럼 클래스가 start인 요소의 input 태그의 name이 login인 요소만을 선택할 수도 있습니다.

var el = document.querySelector(".start input[name=login]");

querySelectorAll() 메소드는 지정된 셀렉터 그룹에 일치하는 다큐먼트의 엘리먼트 리스트를 나타내는 정적(살아 있지 않은) NodeList 를 반환합니다.

var elements = document.querySelectorAll(selectors);




[6. 객체 집합(object collection)을 이용한 선택 ]

HTML DOM에서 제공하는 객체 집합(object collection)을 이용하여 HTML 요소를 선택할 수 있습니다.

var title = document.title;

💭HTMLCollection

HTMLCollection 인터페이스는 요소의 문서 내 순서대로 정렬된 일반 컬렉션(arguments처럼 배열과 유사한 객체)을 나타내며 리스트에서 선택할 때 필요한 메서드와 속성을 제공합니다. 목록을 반복하고 배열과 마찬가지로 숫자가 있는 요소를 참조할 수 있습니다.

배열처럼 보이지만 HTMLCollection에서는 valueOf(), pop(), push() 또는 join()과 같은 배열 메서드를 사용할 수 없습니다.





DOM 요소를 선택하기 위한 다양한 방법을 살펴보며 알게된 것이 있습니다!

바로, 메소드 명에 Elements로 복수형일 경우 HTMLCollection / NodeListCollection 으로 요소를 반환하며,
Element로 단수형일 경우에는 해당 선택자 중 가장 첫번째의 1개 요소만을 반환한다는 것입니다.

또한, 태그, 아이디, 클래스를 각 상황에 맞는 메소드로 선택하는것도 좋은 방법이지만 querySelector 를 사용한다면 더욱 편리하게 사용이 가능합니다.



HTML 요소의 생성


  • Document.createElement()
    HTML 문서에서 지정한 tagName의 HTML 요소를 만들어 반환합니다. tagName을 인식할 수 없으면 HTMLUnknownElement를 대신 반환합니다.
    tag Name 예) div, span, p, input, ...
let element = document.createElement(tagName[, options]);
  • Document.write()
    document.open()에 의해 열린 문서 스팀에 텍스트 스트링을 적는다.
document.write(markup);



HTML 이벤트 리스너 추가

이벤트(event)
웹 브라우저가 알려주는 HTML 요소에 대한 사건의 발생을 의미합니다.
웹 페이지에 사용된 자바스크립트는 이렇게 발생한 이벤트에 반응하여 특정 동작을 수행할 수 있습니다.


이벤트 리스너(event listener)
이벤트가 발생했을 때 그 처리를 담당하는 함수를 가리키며, 이벤트 핸들러(event handler)라고도 합니다.
지정된 타입의 이벤트가 특정 요소에서 발생하면, 웹 브라우저는 그 요소에 등록된 이벤트 리스너를 실행시킵니다.


이벤트 리스너 등록
작성된 이벤트 리스너는 먼저 해당 객체나 요소에 등록되어야만 호출될 수 있습니다.

  1. 이벤트의 대상이 되는 객체나 요소에 프로퍼티로 등록

    • 자바스크립트 코드에서 프로퍼티로 등록 : 이벤트 타입별로 오직 하나의 이벤트 리스너만을 등록 가능

          document.getElementById(아이디).onclick = function(){ 실행할 코드 } //onclick 이벤트
    • HTML 태그에 속성으로 등록 : HTML 코드에 자바스크립트 코드가 추가됨으로써 가독성 하락 및 유지보수 어려움

             <p onclick="alert('문자열을 클릭했어요!')">이 문자열을 클릭해 보세요!</p> //onclick 이벤트




  1. 객체나 요소의 메소드에 이벤트 리스너를 전달
  • addEventListener() : 지정한 유형의 이벤트를 대상이 수신할 때마다 호출할 함수를 설정
    addEventListener() 메소드를 사용하면, 하나의 객체에 여러 개의 이벤트 리스너를 등록할 수 있습니다.
대상객체.addEventListener(이벤트명, 실행할이벤트리스너, 이벤트전파방식)

문법

                addEventListener(type, listener);
                addEventListener(type, listener, options);
                addEventListener(type, listener, useCapture);
  • type : 수신할 이벤트 유형을 나타내는 대소문자 구분 문자열입니다.

  • listener :지정한 이벤트(Event 인터페이스를 구현한 객체)를 수신할 객체입니다. handleEvent() 메서드를 포함하는 객체 또는 JavaScript 함수여야 합니다.

  • options Optional : 이벤트 수신기의 특징을 지정할 수 있는 객체입니다.

  • useCapture[선택사항] : 이벤트 대상의 DOM 트리 하위에 위치한 자손 EventTarget으로 이벤트가 전달되기 전에, 이 수신기가 먼저 발동돼야 함을 나타내는 불리언 값입니다.

    이벤트 버블링과 캡처링은 조상-자손 관계를 가진 두 개의 요소가 동일한 이벤트 유형에 대한 수신기를 가지고 있을 때, 두 요소에 이벤트가 전파되는 방법을 말합니다.

    기본 값은 false 입니다. false면 버블링(bubbling) 방식으로, true면 캡처링(capturing) 방식으로 이벤트를 전파합니다.
    이벤트 버블링과 이벤트 캡처링에 대해서는 이후에 포스팅에서 정리해보겠습니다!

  • attachEvent() : addEventListener() 메소드는 익스플로러 8과 그 이전 버전, 오페라 6과 그 이전 버전에서는 지원하지 않으므로, 대신에 이와 유사한 동작을 하는 attachEvent() 메소드와 detachEvent() 메소드를 사용해야 합니다.
    IE9부터는 지원이 중단되었으며(deprecated) IE11부터는 완전히 제거되었습니다. W3C 표준은 addEventListener 입니다.



DOM tree

DOM tree는 브라우저가 HTML 문서를 로드한 후 파싱하여 생성하는 모델을 의미합니다.
객체의 트리로 구조화되어 있기 때문에 DOM tree라고 부릅니다.

<!DOCTYPE html>
<html>
  <head>
    <style>
      .red  { color: #ff0000; }
      .blue { color: #0000ff; }
    </style>
  </head>
  <body>
    <div>
      <h1>Cities</h1>
      <ul>
        <li id="one" class="red">Seoul</li>
        <li id="two" class="red">London</li>
        <li id="three" class="red">Newyork</li>
        <li id="four">Tokyo</li>
      </ul>
    </div>
  </body>
</html>
DOM에서 모든 요소, 어트리뷰트, 텍스트는 하나의 객체이며 모두 Document 객체의 자식입니다.
객체의 트리로 구조화하여 부모 자식 관계를 표현합니다.
DOM tree의 진입점(Entry point)는 Document 객체이며 최종점은 요소의 텍스트를 나타내는 객체입니다.

DOM tree는 네 종류의 Node로 구성됩니다. 이에 대해 이해하기 위해서는 먼저 Node에 대한 개념을 알아야합니다!
다음 포스팅에서는 Node의 개념과 DOM tree를 구성하는 Node의 종류, Node의 하위개념인 Element까지 알아볼 예정입니다.







참조 링크

profile
즐코 행코 하세용

0개의 댓글