본문 바로가기
  • soldonii's devlog
Javascript 공부/Zero To Mastery(-)

(9) DOM 조작

by soldonii 2019. 8. 27.

*Udemy의 "The Complete Web Developer in 2019 : Zero To Mastery" 강의에서 학습한 내용을 정리한 포스팅입니다.

*https://soldonii.github.io에서 2019년 7월 11일(목)에 작성한 글을 티스토리로 옮겨온 포스팅입니다.

*자바스크립트를 배우는 단계라 오류가 있을 수 있습니다. 틀린 내용은 댓글로 말씀해주시면 수정하겠습니다. 감사합니다. :)


1. DOM이란?

출처 : https://www.udemy.com/the-complete-web-developer-zero-to-mastery/

 

webpage가 로딩되면, browser는 자동으로 위 사진 같은 형태로 구성된 document object를 만든다. 이 document object는 우리가 browser에서 보는 화면 그 자체를 객체로 옮겨놓은 것이며, window라는 객체를 부모 객체(parent object)로 가지고 있다.

  • window 객체는 document 객체에서 가장 큰 부모 객체이며, alert(), prompt() 같은 명령어 또한 window의 children이다.
  • (따라서 alert('blahblah') 대신 window.alert('blahblah') 를 입력해도 결과는 동일하다.)

 

DOM은 왜 필요할까?

DOM은 이용자의 행동에 따라 HTML, CSS를 변경하여 이용자와 상호작용 하기 위해, 즉 web page를 보다 더 interactive하게 만들기 위해 browser가 만든 객체이다.

 

# 자바스크립트 엔진

출처 : https://www.udemy.com/the-complete-web-developer-zero-to-mastery/

모든 browser는 각자 Javascript Engine을 가지고 있다.(ex. google chrome의 경우 V8 Engine) 이 엔진은 Javascript 파일을 한 줄 한 줄 읽어내려가며 browser에서 구동시키는 역할을 한다.

결론적으로, web browser는 DOM 객체를 만들어 HTML과 CSS를 읽으며 이용자의 화면에 보여주며, Javascript Engine은 Javascript을 읽고, 이용자의 행동에 따라 DOM과 상호작용하며 HTML과 CSS를 변경시킨다.

 

2. DOM 선택자

CSS Selector를 통해 HTML에 접근했듯, DOM Selector를 통해 web page의 element에 접근하고 수정할 수 있다. 이 또한 마찬가지로 모든 selector를 정리하는 것은 의미가 없다. MDN, w3schools 같은 사이트를 참고하면 된다. 기본적인 수업 내용만 정리한다.

  • document.getElementsByTagName()
  • document.getElementsByClassName() : 배열을 return한다. 따라서 특정 값에 접근하려면 document.getElementsByClassName()[i] 같은 접근이 필요하다.
  • document.getElementById() : full element를 return한다.
document.getElementByTagName("h1");
document.getElementByClassName("second");
document.getElementById("first");

 

하지만 getElements~ 명령어보다 아래의 querySelector 명령어를 사용하는 것을 권장한다.
  • document.querySelector() : tag, class, id 등 모든 것에 다 접근이 가능하지만, 만일 선택한 element와 동일한 것이 여러개일 경우, 가장 처음 등장하는 element만 return한다. (ex. document.querySelector("li"); 의 경우, 여러 개의 <li> 태그들 중 가장 처음 element만 return.)
  • document.querySelectorAll() : 위 경우 querySelectorAll을 활용하여 여러 element를 모두 선택할 수 있으며, 배열의 형태로 return되므로 index를 통해 특정 element를 선택할 수 있다.

 

선택한 element에 attribute 추가 및 수정하기
  • document.getAttribute() : 선택한 element의 attribute를 return한다.
  • document.setAttribute() : 선택한 element의 attribute를 설정하거나 수정한다.
// <li random="23">Notebook</li>
let li = document.querySelector("li");
li.getAttribute("random"); // "23"

 

# DOM을 이용하여 스타일 변화시키기

DOM 내의 모든 element는 style property를 가지고 있다. 따라서 모든 element에 CSS 스타일을 적용할 수 있으나, separation of concerns의 문제를 안고 있다. 즉, DOM에서 style selector로 CSS를 적용할 경우, CSS 파일에 값이 변경되는 것이 아니라, HTML 파일에서 CSS 서식이 적용되는 문제가 발생한다.

document.querySelector('h1').style.background = "yellow";

 

이를 해결하기 위해서는 CSS 파일에서 특정 class에 대한 서식을 만들어 놓고, 특정 element에 원하는 class를 추가하는 방식을 활용해야 한다.

  • className() : 선택한 element에 class 이름을 부여한다.
  • classList() : 선택한 element가 가지고 있는 class의 list를 배열로 return한다. 아래와 같은 추가 작업이 가능하다.
    • classList.add() : class list에 class를 추가한다.
    • classLists.remove() : class list에서 class를 제거한다.
    • classList.toggle() : class list의 특정 class를 껐다켰다 한다.
let h1 = document.querySelector("h1");
h1.className = "cooltitle";

document.querySelector("li").classList.add("cooltitle");
document.querySelector("li").classList.remove("cooltitle");
document.querySelector("li").classList.add("done");
document.querySelector("li").classList.toggle("cooltitle");

 

이 외에도 innerHTML(HTML 원본 내용을 변경), parentElement(선택한 element의 부모 element를 return), childeren(선택한 element가 가지고 있는 모든 chindren tag를 배열로 return) 등이 있다.

// innerHTML의 경우 원본에 직접적 변경을 가하기 때문에 사용을 지양한다.
document.querySelector("h1").innerHTML = "<strong>!!!!!</strong>"

 

# 변수에 저장하자!

DOM selector를 이용할 때마다, browser는 document 객체에서 element를 찾는 과정을 반복하게 된다. 만일 원하는 element를 변수에 저장하지 않고 계속 DOM selector를 사용하면, 매 단계마다 document 객체를 전부 훑으며 찾기 때문에 메모리 누수가 발생한다.

⇒ 따라서 DOM selector를 이용할 때에는, 선택하고자 하는 element를 항상 변수에 저장하는 습관을 들이자!

 

3. DOM 이벤트

Event란, 사용자가 web page 내에서 행동함으로서 발생하는 모든 것들을 말한다. mouse entering, clicking 등이 있다. 이 또한 마찬가지로, 90% 이상의 경우에서 ‘mouse event’와 ‘keyboard event’만 사용하게 될 것이므로 이를 잘 알아두자.

 mdn DOM events

  • addEventListener : click, mouseenter, mouseleave 
// 이용자가 buttone을 mouse로 click 할때마다 실행된다.
let button = document.getElementByTagName('button')[0];
button.addEventListener("click", function() {
  console.log("CLICK!!");
});

 

  • createElement() : 새로운 element를 생성.
  • createTextNode() : element 안에 입력한 text 생성.
  • appendChild() : 선택한 element의 자식 노드 중 가장 마지막에 붙인다.
  • .value : 특정 element의 값을 불러온다. 예를 들어, <input> tag에 입력된 값을 알고 싶을 경우, getElementsbyTagName("input")[0].value 로 이용한다.
  • .which : keyboardEvent에서 어떤 keyCode(또는 CharCode)가 입력되었는지를 숫자로 알려준다.

 

4. JQuery

앞선 포스팅들에서 언급했듯, 개발자들에게 모든 browser에서 동일한 호환성을 제공하는 것은 중요하지만 어려운 일이었다. 이를 해결하기 위해 등장한 library가 JQuery이다. 그러나 역시 앞서 언급했듯, JQuery는 outdated된 기술이고, 가장 주요한 이유는 코드가 IMPERATIVE해지기 때문이다. IMPERATIVE는 프로그램에게 무엇을 해야할지 정확하게 지정해줘야 한다는 의미이다. 근데 그게 왜 나쁜걸까?

 

JQuery를 사용하면 하나의 액션이 또 다른 액션에 의존하고, 또 다른 액션에 의존하게 된다. 결국 지금 무슨 일이 발생하는지를 추척하는 것이 굉장히 어려워지게 되고, 소위 말하는 pyramid of doom과 같은 현상에 빠지기 쉽다.

출처 : https://www.udemy.com/the-complete-web-developer-zero-to-mastery/

댓글