만두의 부트캠프 🤔
  • 11. DOM
    2023년 11월 01일 16시 37분 30초에 업로드 된 글입니다.
    작성자: 만두33

    # DOM이란?


    DOM은 Document Object Model의 약자로, 웹 페이지의 구조화된 표현을 나타내는 프로그래밍 인터페이스입니다. 

    DOM은 웹 페이지를 나타내는 트리 구조를 형성하며, 이 구조는 웹 페이지의 모든 요소와 그들 간의 관계를 포함합니다. 

    각 HTML 요소, 텍스트, 이미지, 링크, 폼 필드 및 기타 모든 내용은 DOM에서 노드로 표현됩니다.

    DOM은 웹 페이지의 HTML 또는 XML 문서를 메모리에 불러와서 스크립트 언어(일반적으로 JavaScript)를 사용하여 이 문서 구조에 접근하고 조작할 수 있는 방법을 제공합니다. DOM은 웹 페이지에 동적인 기능을 추가하거나 웹 페이지의 내용을 변경하는 데 사용됩니다.

     

     

     

     


     

    # DOM의 특징

     


    DOM은 다음과 같은 주요 특징을 갖습니다:

    1. 트리 구조:  DOM은 트리 구조로 문서의 모든 요소를 표현합니다.

        문서의 최상위 요소는 "문서 노드"이며, 하위 요소는 "요소 노드," "속성 노드," "텍스트 노드" 등으로 구성됩니다.

    2. 접근 및 조작: DOM을 사용하면 웹 페이지의 요소에 접근하고 내용을 변경할 수 있습니다.

        이를 통해 웹 페이지의 동적인 행동을 구현할 수 있습니다.

    3. 언어 독립적: DOM은 특정 프로그래밍 언어와 독립적으로 설계되어 있으며, 

        주로 JavaScript와 함께 사용되지만 다른 스크립트 언어에서도 활용할 수 있습니다.

    4. 이벤트 처리: DOM은 이벤트 처리에 사용되며, 사용자의 상호 작용(클릭, 마우스 이동, 키보드 입력 등)을 감지하고 처리할 수 있습니다.

    DOM을 사용하면 웹 페이지의 구조와 내용을 동적으로 조작하고, 

    웹 애플리케이션의 사용자 경험을 향상시키는 데 필수적인 기술로 사용됩니다.

     

     


    # HTML에 JavaScript 적용하기

     

     

    HTML에 JavaScript를 적용하기 위해서는 <script> 태그를 이용합니다. 아래의 경우 HTML 파일과 같은 디렉토리에 존재하는 myScriptFile.js을 불러옵니다.

    <script src="myScriptFile.js"></script>


    웹 브라우저가 작성된 코드를 해석하는 과정에서 <script> 요소를 만나면, 웹 브라우저는 HTML 해석을 잠시 멈춥니다.

     HTML 해석을 잠시 멈춘 웹 브라우저는 <script> 요소를 먼저 실행합니다. 

    <script> 요소는 등장과 함께 실행된다는 사실을 꼭 기억하세요!!

     

    DOM 구조를 조회할 때에는 console.dir이 유용합니다. console.dir은 console.log와 달리 DOM을 객체의 모습으로 출력합니다. 

    더보기

    "console.dir"은 JavaScript에서 DOM 요소를 객체 형태로 출력해주는 브라우저 콘솔의 메서드입니다. 일반적으로 "console.log"를 사용하면 DOM 요소를 콘솔에 출력할 수 있지만, "console.dir"은 DOM 요소를 더 자세하게 나타내어 객체 형태로 표현해줍니다.

    "console.log"로 DOM 요소를 출력하면 해당 요소의 기본 정보가 표시되고, 주로 요소의 문자열 표현이 출력됩니다. 그러나 "console.dir"을 사용하면 DOM 요소의 속성 및 하위 요소에 대한 더 자세한 정보를 콘솔에 펼쳐서 보여줍니다. 이를 통해 요소의 구조, 속성, 메서드 및 하위 요소를 더 쉽게 살펴볼 수 있습니다.

    예를 들어, "console.log"로는 요소의 텍스트 내용만 볼 수 있지만, "console.dir"을 사용하면 요소의 모든 속성과 하위 요소를 탐색할 수 있어 디버깅과 DOM 구조 이해에 유용합니다.

    간단히 말해, "console.dir"은 DOM 요소를 객체의 구조와 속성을 더 자세히 파악하고 디버깅할 때 도움을 주는 브라우저 콘솔의 메서드입니다.


     

    # DOM 다루기

     

    가장 먼저 이해해야하는 부분은 CRUD(Create, Read, Update and Delete)

    그다음으로는 세세한 메서드들을 알아야 한다.

     


    CREATE

    DOM을 이용하여 HTML Element를 추가하는 방법

     

    1단계

    실습 코드를 받아서 index.html 파일을 브라우저에서 열고, 

    개발자도구의 console 탭에서 예시 코드를 입력하여 

    document 객체의 .createElement 메서드를 이용하여 

    <div> 요소를 만듭니다

    document.createElement('div')

     

    2단계

    JavaScript에서 어떤 작업의 결과를 담으려면 어떻게 해야 할까요? 

    변수를 선언하고 어떤 작업의 결과를 변수에 할당합니다.

     여기서는 div element를 변수 tweetDiv에 할당합니다.

    const tweetDiv = document.createElement('div')

    화면에는 아직 아무런 변화가 없다.

    Div를 트리구조에 포함이되게 설정을 해 줘야한다.

     

    2단계까지 실행 예시

     

     

    공중에 떠있는 엘리먼트를 확인하기 위해서는 APPEND 해야 합니다. 

    APPEND를 이용해 실제 웹 페이지 상에도 보이는 것을 확인할 수 있습니다. 

    APPEND에서, tweetDiv를 트리 구조에 연결합니다.

     


     

    APPEND

     

    .append() 메서드는 DOM 요소에 하나 이상의 노드나 DOMString(텍스트)를 추가하는 데 사용되는 JavaScript 메서드입니다. 

    이 메서드를 사용하면 요소의 자식으로 다른 요소나 텍스트를 추가할 수 있습니다.

    .append() 메서드는 하나의 요소나 여러 요소, 텍스트 노드 등을 동시에 추가할 수 있으며, 그 순서대로 자식 요소로 추가됩니다. 

    이것은 HTML 요소를 동적으로 생성하고 구성할 때 유용한 메서드 중 하나입니다.

     

     

     

    3단계

    CREATE에서 생성한 tweetDiv를 트리 구조와 연결합니다.

    CREATE에서 만든 tweetDiv라는 변수는 아직 "공중부양"을 하고 있습니다.
    append라는 메서드를 사용해서, 변수 tweetDiv를 <body>에 넣어보겠습니다.

    document.body.append(tweetDiv)

     

     

     

    콘솔에 입력함(왼쪽)

    입력 전 모습(중간)

    이후 요소에서 <body>안에 포함된것 확인 가능(오른쪽)


     

     

     

     


    UPDATE

     

     

    DOM을 이용하여 HTML Element를 조회하는 방법을 실습합니다.

     

    DOM으로 HTML 엘리먼트의 정보를 조회하기 위해서는 querySelector의 첫 번째 인자로 선택자(selector)를 전달하여 확인할 수 있습니다. 선택자로는 HTML 요소("div"), id("#tweetList"), class(.tweet) 세 가지가 가장 많이 사용됩니다.

     

     


    querySelector

     

    querySelector와 querySelectorAll은 DOM(Document Object Model)에서 요소를 선택하거나 조회하는 역할을 하는 메서드입니다. 이들은 CSS 선택자를 사용하여 요소를 찾아서 반환하며, JavaScript로 DOM을 다룰 때 매우 유용합니다. 

     

    특성 .querySelector .querySelectorAll
    역할 매칭되는 첫 번째 요소 선택 매칭되는 모든 요소 선택
    반환 값 단일 요소(Element) NodeList (유사 배열)
    CSS 선택자 사용 가능 가능
    단일/복수 선택 단일 요소 선택 모든 요소 선택
    반복적인 조작에 유용 아니오
    성능 고려 빠를 수 있음 많은 요소일 경우 성능 저하 가능

     


    여기서 중요한 포인트는 querySelector은 첫 번째 매칭 요소만 선택하고, 반환 값이 요소(Element)이며, 

    querySelectorAll은 모든 매칭 요소를 선택하고 NodeList를 반환한다는 것입니다. 

    이 차이 때문에 querySelector은 단일 요소를 조회하거나 첫 번째 매칭 요소만 필요한 경우에 유용하며, 

    querySelectorAll은 여러 요소를 선택하고 그들을 반복적으로 조작해야 할 때 유용합니다.

     

     

    (예시코드)

     

     

    [코드] querySelector로 클래스 이름이 tweet인 HTML 요소를 조회합니다.

    const oneTweet = document.querySelector('.tweet')

     

     

     

    [코드] querySelectorAll로 클래스 이름이 tweet 인 모든 HTML 요소를 유사 배열로 받아옵니다.

    const tweets = document.querySelectorAll('.tweet')

     

     

     

    조회한 HTML 요소들은 배열처럼 for문을 사용하실 수 있습니다. 

    주의하세요! 앞서 조회한 HTML 요소들은 배열이 아닙니다! 

    이런 '배열 아닌 배열'을 유사 배열, 배열형 객체 등 다양한 이름으로 부릅니다. 정식 명칭은 Array-like Object입니다. 

     

     

    더보기

    "Array-like object"는 배열과 유사한 동작을 하는 객체를 나타냅니다. 이러한 객체는 배열처럼 여러 항목을 가지고 있으며, 순서가 있고 각 항목은 인덱스로 접근할 수 있습니다. 그러나 배열처럼 자체적으로 배열 메서드와 속성을 가지고 있지는 않습니다.

    Array-like 객체의 주요 특징은 다음과 같습니다:

    1. **인덱스된 요소:** Array-like 객체는 0부터 시작하는 정수 인덱스를 사용하여 항목에 접근할 수 있습니다. 예를 들어, `obj[0]`, `obj[1]`, `obj[2]`와 같이 인덱스를 사용하여 각 항목에 접근할 수 있습니다.

    2. **length 속성:** Array-like 객체는 `length` 속성을 가집니다. 이 속성은 객체에 포함된 요소의 수를 나타내며, 배열의 `length` 속성처럼 작동합니다.

    3. **반복 가능(iterable):** Array-like 객체는 반복문을 사용하여 객체의 항목을 순회할 수 있습니다. 예를 들어, `for...of` 루프나 `forEach` 메서드를 사용하여 객체의 항목에 접근할 수 있습니다.

    4. **Array 메서드 미지원:** Array-like 객체는 배열 메서드(예: `push`, `pop`, `splice` 등)를 직접 사용할 수 없습니다. 그러나 배열 메서드를 사용할 수 있도록 Array-like 객체를 배열로 변환할 수 있습니다.

    주로 DOM 요소, 함수의 `arguments` 객체, 문자열, 및 유사 배열의 데이터 구조 등이 Array-like 객체로 간주될 수 있습니다.

    Array-like 객체를 배열로 변환하려면 다음과 같이 할 수 있습니다:

    ```javascript
    const arrayLikeObj = { 0: 'apple', 1: 'banana', 2: 'cherry', length: 3 };

    const array = Array.from(arrayLikeObj);
    ```

    이렇게 하면 Array-like 객체를 진짜 배열로 변환할 수 있어서 배열 메서드를 사용할 수 있게 됩니다.

     

     

     

    [코드] getElementById와 querySelector로 각각 받아 온 container 요소는 하나의 요소입니다.

    get으로 시작하는 DOM 조회 메서드도 있다. 이런 메서드는 querySelector와 비슷한 역할을 하는 오래된 방식이라고만 이해하면 됩니다. 만약 이전 버전의 브라우저(인터넷 익스플로러) 호환성을 신경 써야 한다면, 이런 옛날 방식을 사용해야 할 수도 있습니다.

    실제 동작은 동일하니 이런 메서드가 있다는 것 정도는 알아두세요.

    const getOneTweet = document.getElementById('container')
    const queryOneTweet = document.querySelector('#container')
    console.log(getOneTweet === queryOneTweet) // true

     

     

     

     

    4단계

    CREATE에서 생성한 div 요소를 container에 넣을 준비를 마쳤습니다.

    다음 코드를 입력하면, container의 맨 마지막 자식 요소로 tweetDiv를 추가합니다.

     

     

    const container = document.querySelector('#container')
    const tweetDiv = document.createElement('div')
    container.append(tweetDiv)

     

     

    코드 입력 전(왼쪽)

    코드 콘솔창에 입력(중간) //2번째줄 코드 빼고 입력

    코드 입력 후, <div>가  container안으로 이동(오른쪽)

     

     

     

    코드 입력으로 tweetDiv를 container의 마지막 자식 요소로 추가하였다.

    새롭게 추가된 tweetDiv는 별도의 class가 지정되어 있지 않아, CSS를 이용한 스타일링이 적용되지 않은 상태이다.

     

     

     

     


    UPDATE

     

     

     

    5단계

     

    oneDiv라는 이름의 <div> 요소를 만들기

    const oneDiv = document.createElement('div');
    console.log(oneDiv) // <div></div>

     

     

     

    기존에 생성한 빈 div 태그를 업데이트하여, 보다 다양한 작업을 할 수 있습니다. 

    먼저, .textContent를 사용해서, 비어있는 div 엘리먼트에 문자열을 입력합니다.

     

    oneDiv.textContent = 'dev';
    console.log(oneDiv) // <div>dev</div>

     

     

     

    앞서 생성한 div 엘리먼트를 container에 append 했을 때, CSS 스타일링이 적용되지 않았습니다.

    CSS 스타일링이 적용될 수 있도록, div 엘리먼트에 class를 추가합니다.

    classList.add를 이용해 'tweet' 클래스를 추가합니다.

    oneDiv.classList.add('tweet')
    console.log(oneDiv) // <div class="tweet">dev</div>

     

     

     

    생성한 엘리먼트에 텍스트를 채웠고, 클래스를 추가하여 스타일링을 적용했습니다. 

    이번에는 .append를 이용해 container의 자식 요소로 추가합니다.

     

    const container = document.querySelector('#container') //위에서 입력했음 생략
    container.append(oneDiv) //이 줄만 입력

     

     

    append를 이용해 container의 자식 요소에 oneDiv를 추가합니다.
    새롭게 추가한 엘리먼트는 클래스 tweet의 스타일이 적용된 상태로 출력됩니다.(오른쪽)

     

     

     

     

     

    * 참고내용

     

    class와 id 말고는 다른 attribute를 추가하는 방법?

     setAttribute라는 메서드가 있다!

     

     

    더보기

    `setAttribute`는 JavaScript의 DOM(Document Object Model)에서 사용되는 메서드 중 하나로, 요소(Element)의 속성(attribute)을 설정하거나 업데이트할 때 사용됩니다. 이 메서드를 사용하여 속성을 동적으로 조작할 수 있습니다.

    `setAttribute` 메서드는 다음과 같이 사용됩니다:

    ```javascript
    element.setAttribute(attributeName, attributeValue);
    ```

    - `element`: 속성을 설정하려는 요소입니다.
    - `attributeName`: 설정하려는 속성의 이름(문자열)입니다.
    - `attributeValue`: 설정하려는 속성의 값을 나타내는 문자열입니다.

    예를 들어, HTML 요소의 `src` 속성을 변경하려면 다음과 같이 `setAttribute`를 사용할 수 있습니다:

    ```javascript
    const imgElement = document.querySelector('img');
    imgElement.setAttribute('src', 'new-image.jpg');
    ```

    위의 코드는 이미지 요소의 `src` 속성을 "new-image.jpg"로 변경합니다.

    `setAttribute`를 사용하면 다양한 HTML 요소의 속성을 설정하거나 업데이트할 수 있으며, 동적으로 속성을 조작할 때 유용합니다.

     

     

     


     

    DELETE

     

     CRUD의 Delete, 삭제하는 방법에도 여러 가지가 있습니다.

     삭제하려는 요소의 위치를 알고 있을때 .remove 메서드를 사용할 수 있다.

     

     

    앞서 생성하고 추가한 tweetDiv를 삭제합니다.

     

    const container = document.querySelector('#container')
    const oneDiv = document.createElement('div')
    container.append(oneDiv)
    oneDiv.remove() // 이렇게 append 했던 요소를 삭제할 수 있다.

     

    oneDiv.remove()를  console 입력한 후 
    만들어졌던 dev 박스가 없어졌다.

     

     

     

     

     

    다른 방법인 .innerHTML 로는 여러개의 자식요소를 지울 수 있다!

    아래 코드는 id가 container인 요소 아래의 모든 요소를 지운다.

    document.querySelector('#container').innerHTML = '';

     

     

    innerHTML은 보안적 문제가 있다고 한다.

    또다른 방법인 .removeChild는 자식 요소를 지정해서 삭제할 수 있다.

    모든 자식 요소를 삭제하기 위해, 반복문(while, for, etc.)을 활용할 수 있습니다.

    다음의 코드는 자식 요소가 남아있지 않을 때까지, 첫 번째 자식 요소를 삭제하는 코드입니다.

     

    const container = document.querySelector('#container');
    while (container.firstChild) {
      container.removeChild(container.firstChild);
    }

     

     

    위 코드 실행시 모든 요소들이 다 지워진다.

     

     


     

     

    removeChild와 while을 이용해 자식 요소를 삭제하면, 

    제목에 해당하는 H2 "Tweet List"까지 삭제됩니다. 

     

     

    이를 방지하기 위한 방법은 여러 가지가 있습니다.

     자식 요소가 담고 있는 문자열을 비교해 "Tweet List"만 남기거나, 

    새로운 변수를 생성하고 Tweet List를 할당해 뒀다가 반복문이 끝난 뒤에 새롭게 추가할 수도 있습니다. 

    또는 자식 요소를 하나만 남기게 할 수도 있습니다.

     

     

    [코드] container의 자식 요소가 1개만 남을 때까지, 마지막 자식 요소를 제거합니다.

    const container = document.querySelector('#container');
    while (container.children.length > 1) {
      container.removeChild(container.lastChild);
    }

     

     

     

    또는 직접 클래스 이름이 tweet인 요소만 찾아서 지우는 방법도 있습니다.

    const tweets = document.querySelectorAll('.tweet')
    tweets.forEach(function(tweet){
        tweet.remove();
    })
    // or
    for (let tweet of tweets){
        tweet.remove()
    }

     

     

     


    # 정리

     

    .createElement 요소만들기
    .append() 요소 추가하기
    .querySelector 단일요소 선택,조회
    .querySelectorAll 모든 요소 선택, 조회
    .textContent 요소에 텍스트 입력
    classList.add 클래스 추가
    .remove 요소의 위치를 알고있을때 삭제
    .innerHTML 여러개의 자식요소 지우기
    .removeChild 자식요소 지정해서 삭제

     

     

     

    끝!!

    '💻 코드스테이츠 x 경남abclab > Section 1' 카테고리의 다른 글

    10-2. [JavaScript] JavaScript Koans  (0) 2023.10.30
    9-2. [JavaScript] 스코프  (1) 2023.10.27
    9-1. [JavaScript] 자료형, 복사  (0) 2023.10.27
    8-2. [JavaScript] 객체  (1) 2023.10.26
    8-1. [JavaScript] 배열  (0) 2023.10.25
    댓글