[TIL] Day16-DOM

공부중인 개발자·2021년 4월 26일
0

TIL

목록 보기
16/64
post-thumbnail

Dom

DOM은 Document Object Model의 약자로, HTML 요소를 Object(JavaScript Object)처럼 조작(Manipulation)할 수 있는 Model
자바스크립트를 사용할 수 있으면, DOM으로 HTML을 조작할 수 있다.

자바스크립트에서 DOM은 document 객체에 구현
브라우저에서 작동되는 자바스크립트 코드에서는, 어디에서나 document 객체를 조회할 수 있다.

html에 자바스크립트 적용

HTML에 JavaScript를 적용하기 위해서는 <script> 태그를 이용, <script> 요소는 등장과 함께 JavaScript가 실행된다

  • <script> 요소를 <head>에 넣을 경우
    body에 들어가는 script는 진행되지 않는다. script요소가 이미 head에서 실행됐기 때문이다.

  • <body> 태그가 끝나기 전에 삽입하는 경우
    html의 body가 모두 진행되고 script요소가 실행되기 때문에 모든 script가 진행된다.

그러므로 <body> 태그 마지막에 script 요소를 집어넣어줘야 올바르게 진행된다.

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

<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>

위의 예시에서 body element의 자식 element의 개수는 총 3개다.
<div id="nav">, <div id="news-contents">, <div id="footer">(닫는 태그 생략)
<div class="logo"> 같은 경우는 body element의 자식 element가 아닌 <div id="nav">의 자식 element 이다.

console.dir(document.body); // document.body를 조회하는 명령어
//console.dir 은 console.log 와 달리 DOM을 객체의 모습으로 출력
  • 자식 엘리먼트 찾기
    console.dir(document.body.children)
    body 안의 엘리먼트를 작성하면 바로 찾을 수 있다.

  • <div id="news-contents">의 부모 엘리먼트 찾기
    body 엘리먼트는 id가 news-contents div 엘리먼트의 부모 엘리먼트
    console.dir(document.body.children[1]) 이렇게 하면 <div id="news-contents">를 조회할 수 있다.
    Node.parentElement 는 부모 엘리먼트를 가리키는 속성이다.
    <div id="news-contents">의 부모를 찾기 위해서는 여러가지를 이용할 수 있는데 그중 ID를 가지고 있을 때 사용하는 요소 getElementById를 이용해보자

let newsC = document.getElementById('news-contents') //newsC라는 변수에 자식요소를 담아주고
let parent = newsC.parantNode; // newsC의 부모 엘리먼트를 찾는다. 이렇게 되면 부모엘리먼트를 가르킬 수 있다.

DOM으로 HTML 조작하기

CREATE - createElement

document.createElement('div') // 임의의 <div></div> 만든다. (소속된 곳 없음)
const menu = document.createElement('div') //새롭게 생성한 div element를 변수에 할당

createElement를 이용하면 HTML에 element를 추가하지 않고 js로도 추가할 수 있다.

APPEND - append, appendChild

document.body.append(menu) // 변수 menu를 body 엘리먼트에 append(추가)해줌
//임의의 엘리먼트를 다른 엘리먼트에 연결해주는 것

append 와 appendChild는 모두 부모노드에 자식노드를 연결해주는 메서드이다.

둘의 차이점을 간단하게 나타낸 블로그이다.
https://webruden.tistory.com/634

참고) 같은 엘리먼트를 appendChild 하면 복사되지 않는다. a, b로 변수가 지정되어있는 두개의 엘리먼트 중 a 안에 span 태그가 있고 이 span 태그를 b.appendChild('span') 한다면 a의 태그는 사라지고 b로 옮겨져 있다.

READ - querySelector, querySelectorAll

  • DOM으로 HTML 엘리먼트의 정보를 조회하기 위해서는 querySelector의 첫 번째 인자로 셀렉터(Selector)를 전달하여 확인

  • 셀렉터로는 HTML 태그("div"), id("#nav"), class(".menu") 세 가지가 가장 많이 사용

  • querySelector 에 '.menu' 을 첫 번째 인자로 넣으면, 클래스 이름이 menu 인 HTML 엘리먼트 중 첫 번째 엘리먼트를 조회할 수 있다.
    const oneTweet = document.querySelector('.menu')

  • 여러 개의 엘리먼트를 한 번에 가져오기 위해서는, querySelectorAll 을 사용
    이렇게 조회한 HTML 엘리먼트들은 배열처럼 for문을 사용할 수 있다. 배열처럼이지만 배열은 아니다.

const menus = document.querySelectorAll('.menu')
const menuWrapper = document.querySelector('.menu-wrapper')
const menuDiv = document.createElement('div')
menuWrapper.append(menuDiv)
//menuDiv를 menuWrapper의 마지막 자식 요소로 추가

UPDATE - textContent, classList.add

  • textContent 를 사용해서, 비어있는 div 엘리먼트에 문자열을 입력
let test = document.createElement('div')
console.log(test) // <div></div>
test.textContent = 'test check';
console.log(test) // <div>test check</div>
  • div 엘리먼트에 class를 추가
test.classList.add('profile-photo')
console.log(test) // <div class="profile-photo">test check</div>
  • append를 이용해 menu-wrapper의 자식 요소로 추가
const menuWrapper = document.querySelector('.menu-wrapper')
menuWrapper.append(test)

자식요소를 추가한 결과

 <div class="menu-wrapper">
        <div class="menu"></div>
        <div class="menu"></div>
        <div class="menu"></div>
        <div class="profile-photo"></div>
	<div class="profile-photo">'test check'</div>

DELETE - remove, removeChild

  • 앞서 생성하고 추가한 test 를 삭제, remove 메소드를 사용
const menuWrapper = document.querySelector('.menu-wrapper')
const test = document.createElement('div')
menuWrapper.append(test)
test.remove()
  • innerHTML 을 이용하면 모든 자식 엘리먼트를 지울 수 있다
document.querySelector('.menu-wrapper').innerHTML = ''; // class가 .menu-wrapper인 엘리먼트 아래의 모든 엘리먼트를 지웁니다.
  • removeChild 는 자식 엘리먼트를 지정해서 삭제하는 메소드
    다음의 코드는 자식 엘리먼트가 남아있지 않을 때까지, 첫 번째 자식 엘리먼트를 삭제하는 코드
const menuWrapper = document.querySelector('.menu-wrapper');
while (menuWrapper.firstChild) {
  menuWrapper.removeChild(menuWrapper.firstChild);
}
  • removeChild 와 while 을 이용해 자식 요소를 삭제하면, 메뉴가 모두 삭제된다. 프로필 포토만 삭제하고 싶을 때는
const menuWrapper = document.querySelector('.menu-wrapper');
while (menuWrapper.children.length > 3) {
  menuWrapper.removeChild(menuWrapper.lastChild);
}
  • 직접 클래스 이름이 menu인 엘리먼트만 찾아서 지우는 방법
const menus = document.querySelectorAll('.menu')
menus.forEach(function(menu){
    menus.remove();
  })
// or
for (let menu of menus){
    menu.remove()
}

그 외 알아야할 것 (자주 보면서 외우자)

Node 는 Element의 상위 개념이다.

자바스크립트 객체의 구조는 트리구조이다.
document.cloneNode 는, 생성하는 메소드가 아니라 복제하는 메소드
document.querySelector 는 , 생성하기 위한 메소드가 아니라 조회하는 메소드
document.importNode 는, template 을 활용하여 내용을 붙여넣을 때 사용하는 메소드

document.getElementsByTagName('div') tag이름이 div 인 element 여러 개를 조회
document.getElementById('div') id가 div 인 element 하나를 조회
document.getElementsByClassName('div') class가 div 인 element 여러 개를 조회

element.innerHTML = 'Hi' // element의 내용에 'Hi' 를 집어넣는다.
element.setAttribute('name', 'value') // name이 키, value 가 값이다. 예를 들어 div.setAttribute('class', 'username') 이렇게 들어가면

같은 태그가 만들어진다.

이미 삽입한 element 지우기
element.remove()
document.querySelector("#id").removeChild(element)


마지막으로...

DOM이라는것을 처음 경험 했을 때가 계산기 만들 때 이미 만들어져있던 querySelector 였던거 같은데 이제 직접 사용하는걸 배우네... 이해하는데 한참 걸렸다. 최소 4번은 더 읽어봐야겠다.

profile
열심히 공부하자

0개의 댓글