DOM

Verba volant, scripta manent·2021년 1월 15일
0

JavaScript

목록 보기
11/20
post-thumbnail

DOM이란?

Document Object Model
HTML(Document)에 접근하여 Object(JavaScript Object)처럼 HTML을 조작(Manipulation)할 수 있는 Model

-> 자바스크립트를 사용하는 방법을 알고 있으면 DOM을 활용하여 HTML을 조작할 수 있다.

HTML이 JavaScript에서는 어떻게 표현이 될까?

ex)

<html>
  <body>
    <div id="nav">
      <div class="logo"></div>
      <div class="menu-wrapper">
        <div class="menu"></div>
        <div class="menu"></div>
        <div class="menu"></div>
        <div class="profile-photo"></div>
      </div>
    </div>
    <div id="news-contents">
      <div class="news-content-wrapper">
        <div class="news-picture"></div>
        <div class="news-title"></div>
        <div class="news-description"></div>
      </div>
    </div>
    <div id="footer"></div>
  </body>
</html>
  1. 여기서 body 엘리먼트의 자식 엘리먼트(element)는 총 몇 개인가?
  2. class의 이름이 news-contentsdiv 엘리먼트의 부모 엘리먼트는 무엇인가?
  3. id의 이름이 navdiv엘리먼트 를 포함해서, 모든 자식 엘리먼트의 class 이름을 console.log를 사용하여 확인하려면 어떻게 해야 할지 수도코드(pseudocode)를 작성하라.

위의 질문은 천천히 답을 할 것이다.

1. 자식 엘리먼트 찾기

  1. body 엘리먼트의 자식 엘리먼트(element)는 총 몇 개인가?

위에서 내린 3개의 질문 중 첫번째 질문에 대한 답변은 바로 3개이다.
body 엘리먼트의 자식 엘리먼트는 총 3개이다.
id가 nav, news-contents, footer 인 3가지 엘리먼트이다.

그럼 자바스크립트는 어떻게 인식할까?
자바스크립트에서 DOM은 document 객체에 구현되어 있다.
브라우저에서 작동하는 자바스크립트 코드에서는 어디에서나 document객체를 조회할 수 있다.

DOM 구조를 조회하기 위해서는 console.dir이 유용하다.
DOM을 객체의 모습으로 보여준다.

여기서 자식 엘리먼트를 찾아보자.
children을 찾아보면

이렇게 속성이 나온다.
물론, document.body.children으로 조회할 수도 있다.

2. 부모 엘리먼트 찾기

  1. id가 news-contents인 div 엘리먼트의 부모 엘리먼트는 무엇인가?

두번째 질문의 답은 body이다.

자바스크립트에서도 확인할 수 있는데, document.body.children의 첫번째 엘리먼트를 조회해보자.

첫번째 엘리먼트가 div#news-contents라고 나온다.

여기서 매번 document.body로 찾아가는건 매번 번거로우므로 따로 변수 newsContents를 선언을 해서 저장해둘 수 있다.

3. DOM 순회하기

  1. id의 이름이 nav인 div 엘리먼트 를 포함해서, 모든 자식 엘리먼트의 class 이름을 console.log를 사용하여 확인하려면 어떻게 해야 할지 수도코드(pseudocode)를 작성하라.

DOM 구조의 특성을 보면 조직도가 생각나게끔 한다.

부모가 자식을 여러개 가지고, 부모가 하나인 구조가 계속 반복된다.

이를 수도코드로 작성하면 이렇게 된다.

function consoleLogAllElement(element){
// nav의 class 이름을 console.log 한다.
// nav의 자식 엘리먼트가 있는지 검색한다. (logo, menu-wrapper)
  //logo의 class 이름을 console.log 한다.
  //logo의 자식 엘리먼트가 있는지 검색한다. (없음)
  //menu-wrapper의 class 이름을 console.log 한다.
  //menu-wrapper의 자식 엘리먼트가 있는지 검색한다.
  (menu, menu, menu, profile-photo)
    //첫 번째 menu의 class 이름을 console.log 한다.
    //첫 번째 menu의 자식 엘리먼트가 있는지 검색한다. (없음)
    //두 번째 menu의 class 이름을 console.log 한다.
    //두 번째 menu의 자식 엘리먼트가 있는지 검색한다. (없음)
    //세 번째 menu의 class 이름을 console.log 한다.
    //세 번째 menu의 자식 엘리먼트가 있는지 검색한다. (없음)
    //profile-photo의 class 이름을 console.log 한다.
    //profile-photo의 자식 엘리먼트가 있는지 검색한다 (없음)
 //자식 엘리먼트를 모두 탐색했음으로, 함수 실행이 종료된다.
//자식 엘리먼트를 모두 탐색했음으로, 함수 실행이 종료된다.
}

DOM 조작

DOM을 JavaScript로 조작하여 HTML Element를 추가하거나 삭제, 혹은 내용을 변경할 수 있다.

CREATE - createElement

document.createElement(HTML요소)
지정된 HTML 요소를 생성한다.

ex)
document.createElement('div')
<div></div>

APPEND - append, appendChild

.append()
해당 노드에 새로운 요소를 부여한다.

위에서 생성한 요소 document.createElement('div')를 변수로 선언하여 결과로 할당하여
let tweetDiv = document.createElement('div') 를 만들었다.

body에 선언했던 변수 요소를 넣는다고하면
document.body.append(tweetDiv) 라고 쓴다.

append() 와 appendChild() 의 차이점

append() appendChild()
자바스크립트 메소드 DOM 메소드
문자열, 텍스트 노드, 엘리먼트 노드 삽입 가능 노드 객체만 삽입 가능
노드 갯수 여러개 허용 노드 갯수 하나만 허용

append()와 prepend()의 차이점

append() prepend()
컨텐츠를 선택된 요소 내부의 끝 부분에서 삽입 컨텐츠를 선택한 요소 내부의 시작 부분에서 삽입
ex)
<p>코딩</p> 이렇게 있을 경우
append()는 <p>코딩 여기에값이들어간다.</p>
prepend()는 <p>여기에값이들아간다. 코딩</p>

READ - querySelector, querySelectorAll

document.querySelector()
특정 선택자(id나 class)를 가진 첫번째 요소를 선택한다.

  1. id 태그를 조회할 때는 이름 앞에 #을 붙힌다.
    ex) document.querySelector('#tweet')
  2. class 태그를 조회할 때는 이름 앞에 .을 붙힌다.
    ex) document.querySelector('.tweet')

document.querySelectorAll()
특정 선택자(id나 class)를 가진 모든 요소를 선택한다.

  1. id 태그를 조회할 때는 이름 앞에 #을 붙힌다.
    ex) document.querySelectorAll('#tweet')
  2. class 태그를 조회할 때는 이름 앞에 .을 붙힌다.
    ex) document.querySelectorAll('.tweet')

UPDATE - textContent, classList.add

.textContent
태그 사이에 내용을 넣는다.

ex) tweetDiv.textContent = 'Yeonlisa'; // <div>Yeonlisa</div>

.classList.add()
해당 태그에 클래스를 지정한다.

ex) tweetDiv.classList.add('tweet'); // <div class="tweet">Yeonlisa</div>

textContent와 innerHTML의 차이

textContent
요소의 텍스트 콘텐츠를 취득 또는 변경한다. 이때 마크업은 무시된다.
textContent를 통해 요소에 새로운 텍스트를 할당하면 텍스트를 변경할 수 있다.
이때 순수한 텍스트만 지정해야 하며 마크업을 포함시키면 문자열로 인식되어 그대로 출력된다.

innerHTML
해당 요소의 모든 자식 요소를 포함하는 모든 콘텐츠를 하나의 문자열로 취득할 수 있다.
이 문자열은 마크업을 포함한다.

innerHTML의 보안상 단점

XSS(Cross-Site Scripting) 공격에 취약하다.

DELETE - remove, removeChild

.remove()
태그를 삭제한다.

let container = document.querySelector('#container')
let tweetDiv = document.createElement('div') // <div></div>
container.append(tweetDiv) // 부모인 container 에 tweetDiv 를 넣는다.
tweetDiv.remove() // 이렇게 append 했던 엘리먼트를 삭제할 수 있다.

.removeChild()
태그의 자식만 삭제한다.

const container = document.querySelector('#container');
while (container.children.length > 1) {
  container.removeChild(container.lastChild);
} // 자식을 하나만 남겨두고 모두 제거한다. 

remove()와 removeChild()의 차이점

remove() 는 노드를 메모리에서 삭제하고 종료한다.

removeChild()는 노드를 삭제하는 것이 아니라 메모리에 해당 노드는 그대로 존재하며, 부모 노드와의 부모-자식관계를 끊어 DOM 트리에서 해제하는 것이다.

그외

element와 node의 차이점

node는 element의 상위 개념이다.

children과 childNodes의 차이점

children은 현재 요소의 자식 요소가 포함된 HTML Collection을 반환한다.(자식 요소에 접근)
childNodes는 현재 요소의 자식 노드가 포함된 NodeList를 반환한다.(자식 노드에 접근)

profile
말은 사라지지만 기록은 남는다

0개의 댓글