본문 바로가기
개발 관련/javascript

10. DOM

by lazysnack 2022. 7. 13.
  1. DOM 을 노드의 계층 구조로 이해
  2. 다양한 노드 타입
  3. 브라우저들 간의 비호환성을 우회하는 DOM 코딩

1. 노드의 계층 구조

  • HTML 과 XML 문서는 모두 DOM 을 통해 노드의 계층 구조로 표현 가능

    <html>
      <head>
        <title>Sample</title>
      </head>
      <body>
        <p>Hello</p>
      </body>
    </html>
    • 문서 노드(Document) 는 각 문서를 루트로 표현함. 위에서 문서 노드의 자식은 하나 뿐인데 이를 문서요소 라고 함
    • 문서 요소는 문서의 최상위 요소이며 다른 요소는 모두 이 안에 존재
    • 문서 하나에 문서 요소 하나만 있을 수 있음

2. 다양한 노드 타입

2-1 Node 타입

  • DOM 레벨 1에는 Node 라는 인터페이스가 존재

  • 각 노드에는 childNodes 라는 프로퍼티가 있는데 이 프로퍼티에는 NodeList 가 저장됨

  • NodeList는 처음 호출했을 때 얻은 결과를 저장하고 있는 것이 아니라 계속 바뀌므로 살아있는 객체라고 부르기도 함

    var firstChild = someNode.childNodes[0];
    var secondChilde = someNode.childNodes.item(1);
    var count = someNode.childNodes.length; // 2
    
    someNode.childNodes.appendChild(newNode);
    console.log(count); // 3
  • 각 노드에서는 문서 트리에서 부모를 가르키는 parentNode 프로퍼티가 있으며, childNodes 목록에 각 노드는 형재관계로 previousSibling, nextSibling 으로 접근 가능하며, 부모 입장(parentNode) 에서는 firstChild, lastChild 로 접근 가능

  • 노드 조작 메소드

    1. appendChild() - childNodes 목록 마지막에 노드 추가
    2. insertBefore() - childNodes 특정 위치에 삽입
    3. replaceChild() - 기존 노드 교체
    4. removeChild() - 노드 삭제
    • replaceChild() 와 removeChild() 는 해당 문서의 소유이긴 하지만 문서에서 위치를 지정받진 못한 상태라 볼 수 있음
  • cloneNode()

    // 자손 노드 전체 복사
    var deepList = myList.cloneNode(true);
    
    // 해당 노드 하나만 복사
    var shallowList = myList.cloneNode(false);

2-2 Document 타입

  • 문서 노드를 Document 타입으로 표현

  • window의 프로퍼티이므로 전역에서 접근 가능

    var html = document.documentElement; // <html>
    var body = document.body; // <body>
    var doctype = document.doctype; // <!DOCTYPE>
    
    var title = document.title; // title 가져오기
    document.title = "new Title"; // title 변경
  • 요소 위치

    <img src="myImage.png" name="myImage1" id="myImage">
    
    // 요소 ID 를 매개변수로 받음
    var imgById = document.getElementById('myImage');
    
    // 요소 tag name 을 매개변수로 받음
    var imgByTag = document.getElementByTagName('img');
    
    // 요소 name 을 매개변수로 받음
    var imgByName = document.getElementByName('myImage1');
  • 문서에 쓰기

    <html>
      <head>
        <title>document.write() Example</title>
      </head>
      <body>
        <script type="text/javascript">
            document.write("<script type=\"text/javascript\" src=\"file.js\">" + "<\/script>");
        </script>
      </body>
    </html>

2-3 Element 타입

  • HTML 요소

    • Id - 요소의 고유 식별자
    • title - 요소의 추가정보로 일반적으로 툴팁으로 표현됨
    • classNmae - 요소의 CSS 클래스인 class 속성
  • 속성 얻기

    • getAttribute()

    • setAttribute()

    • removeAttribute()

    • 주로 커스텀 속성을 다룰 때 사용
    div.myColor = "blue";
    console.log(div.getAttribute("myColor")); // null
    • 대부분의 브라우저에서 이 프로퍼티는 자동으로 요소 속성이 되지는 않으므로 getAttribute()로 같은 이름의 속성에 접근하면 null 을 반환
  • 요소 생성

    var div = document.createElement('div');
    div.id = "myNewDiv";
    div.className = "box";
    
    // 생성한 요소를 문서 트리에 추가해야 반영
    document.body.appendChild(div);

2-4 Text 타입

  • 평범한 텍스트가 포함되고, 글자 그대로 사용됨

  • 이스케이프된 HTML 문자는 포함할 수 있지만, HTML 코드는 포함 불가능

    var textNode = document.createTextNode("<strong>hello</strong> wolrd");
    
    element.appendChild(textNode);
    
    document.body.appendChild(element);

2-5 Comment 타입

  • 주석은 DOM 에서 Comment 타입으로 표현

    var comment = document.createComment("comment");

2-6 CDATASection 타입

  • XML 기반 문서 전용 (myBatis를 사용하면 자주 봄)

    <div id="myDiv"><![CDATA[this is some content.]]></div>

2-7 DocumentType 타입

  • 문서의 독타입 정보

    <!DOCTYPE HTML PUBLIC "-//W3C" ~~~~>
    
    console.log(document.doctype.name); // HTML

3. DOM 다루기

  • DOM 조작은 단순하며, 자바스크립트를 쓸 때도 일반적인 HTML 코드와 마찬가지로 하면 됨 (언제나 예외는 있지만..)

3-1 동적 자바스크립트

  • <script type="text/javascript" src="client.js" />
  • function loadScript(url) {
      var script = document.createElement('script');
      script.type = "text/javascript";
      script.src = url;
      document.body.appendChild(script);
    }
    
    loadScript("client.js")

3-2 동적 스타일

  • <link rel="stylesheet" type="text/css" href="styles.css">
  • function loadStyles(url) {
        var link = document.createElement('link');
      link.rel = "stylesheet";
      link.type = "text/css";
      link.href = "style.css";
      var head = document.getElementByTagName('head')[0];
      head.appendChild(link);
    }
    
    loadStyles("styles.css");

3-3 노드리스트 사용

  • 살아있는 객체로 간주되기에 무한 루프가 될 수 있음

    var divs = document.getElementByTagName('div'),
        i,
        div;
    
    for(i = 0; i < divs.length; i++) {
      div = document.createElement('div');
      document.body.appendChild(div);
    }
    // 루프가 반복될 때마다 i < divs.length 조건을 확인하는데
    // divs.length 가 계속 갱신되므로 무한 루프
    var divs = document.getElementByTagName('div'),
        i,
        len,
        div;
    
    for(i = 0, len = divs.length; i < len; i++) {
      div = document.createElement('div');
      document.body.appendChild(div);
    }
  • 컬렉션에 접근할 때마다 다시 쿼리 하므로, 일반적으로 NodeList 자체에 접근하는 일은 되도록 피하는 것이 좋음. 사용한다면 변수에 저장하여 사용

'개발 관련 > javascript' 카테고리의 다른 글

13. 이벤트  (0) 2022.07.13
11. DOM 확장  (0) 2022.07.13
8. 브라우저 객체 모델  (0) 2022.07.13
7. 함수 표현식  (0) 2022.07.13
6. 객체 지향 프로그래밍  (0) 2022.07.13