12월 23일 복기

Ji Taek Lim·2020년 12월 23일

DOM에 대해서 해보자..

다시 해보자.. DOM..

DOM은 Document Object Model의 약자로, HTML(Document)에 접근하여 Object(JavaScript Object)처럼 HTML을 조작(Manipulation)할 수 있는 Model이라는 의미를 가지고 있습니다. 즉, 여러분이 자바스크립트를 사용하는 방법을 알고 있으면 DOM을 활용하여 HTML을 조작할 수 있다는 의미입니다.

HTML을 조작할 수 있다는게 무슨 의미일까요? 지금까지 여러분이 만든 트위틀러 목업의 홈페이지의 버튼을 눌렀을 때 잘 작동했나요? 아마 잘 작동하지 않았을 겁니다. DOM은 HTML의 아주 작은 부분까지 접근할 수 있도록 여러 뛰어난 웹 개발자들이 모여 철저히 분석하여 준비된 구조(Model; Structure)입니다. 자바스크립트는 이 구조를 잘 활용하여 HTML로 구성된 웹 페이지를 작동하게 만들 수 있습니다. 우리가 배웠던 반복문과 조건문, 배열, 객체를 활용하여 생성되는 트윗을 저장하고 분류하는 작업 또한 할 수 있습니다.

자바스크립트는 다양한 일을 할 수 있지만, 전통적으로 브라우저를 제어하기 위해서 오랜 기간동안 사용 되어왔기 때문에, 웹 개발에 가장 좋은 언어입니다. DOM을 공부하여 홈페이지를 조금 더 다이나믹하게 만들어 봅시다!

DOM과 자바스크립트의 차이
https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction#DOM_and_JavaScript

우리 모두 열심히 HTML에 대해서 배웟습니다. 한번 아래 구조에 대해서 분석을 해봅시다. 아래와 같은 단순한 HTML이 있습니다. 아래 질문에 대해서 어떻게 문제를 코드로 해결할 수 있을지 고민해주세요.

body 엘리먼트의 자식 엘리먼트(element)는 총 몇 개인가요?
class의 이름이 news-contents 인 div 엘리먼트의 부모 엘리먼트는 무엇인가요?
id의 이름이 nav인 div엘리먼트 를 포함해서, 모든 자식 엘리먼트의 class 이름을 console.log를 사용하여 확인하려면 어떻게 해야 할지 수도코드(pseudocode)를 작성해주세요


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

3개 아닌가?

class 가 아니고 id 아닌가?

모든 자식엘리먼트를 순회하는 수도코드를 작성한다?

아이디가 nav인애한테 가서 너희집 애들이 몇명 있는지 물어봐..

그림으로 표현하기는 쉽지만, 컴퓨터에게는 어떻게 인식시킬까요? 자바스크립트에서 DOM은 document 객체에 구현되어 있습니다. 브라우저에서 작동되는 자바스크립트 코드에서는 어디에서나 document 객체를 조회할 수 있습니다. 한번, body를 찾아보겠습니다.

DOM 구조를 조회하기 위해서는 console.dir이 유용합니다. console.log와 달리 DOM을 객체의 모습으로 보여주는 친구입니다. 앞으로 console.log와 console.dir의 차이를 구분해서 사용하실 일이 계속 있을겁니다 🙂

document.body를 조회해보니, 내가 모르는 것들이 정말 많이 보입니다. 생각해보면 우리가 배웠던 HTML 엘리먼트에 지정할 수 있었던 다양한 속성이 있던 것을 기억하실겁니다. 그 많은 속성에 미리 이름을 지어두었다고 생각하시면 됩니다.

우리가 원하는 자식 엘리먼트를 찾아봅시다. 이번에는 힌트를 드리겠습니다. children을 찾아볼까요?

https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement


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의 자식 엘리먼트가 있는지 검색합니다 (없음)
 //자식 엘리먼트를 모두 탐색했음으로, 함수 실행이 종료됩니다.
//자식 엘리먼트를 모두 탐색했음으로, 함수 실행이 종료됩니다.
}



이거 어떻게 하는거야... 알려주실분..

Achievement Goals
DOM을 JavaScript로 조작하여 HTML Element를 추가하거나 삭제, 혹은 내용을 변경할 수 있다.
createElement - CREATE
querySelector, querySelectorAll - READ
textContent, id, classList, setAttribute - UPDATE
remove, removeChild, innerHTML = "" , textContent = "" - DELETE
appendChild - APPEND
innerHTML과 textContent의 차이

Document.createDocumentFragment()
https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment


document.createElement('div')
const tweetDiv = document.createElement('div')

var fragment = document.createDocumentFragment();

Usage notes
DocumentFragments are DOM Node objects which are never part of the main DOM tree. The usual use case is to create the document fragment, append elements to the document fragment and then append the document fragment to the DOM tree. In the DOM tree, the document fragment is replaced by all its children.

Since the document fragment is in memory and not part of the main DOM tree, appending children to it does not cause page reflow (computation of element's position and geometry). Historically, using document fragments could result in better performance.

해석하자면 html에 안넣어주고 어디다가 만들어서 넣어줘서 퍼포먼스를 좀 더 좋게 해준다는거다.


<ul id="ul">
</ul>

var element  = document.getElementById('ul'); // assuming ul exists
var fragment = document.createDocumentFragment();
var browsers = ['Firefox', 'Chrome', 'Opera',
    'Safari', 'Internet Explorer'];

browsers.forEach(function(browser) {
    var li = document.createElement('li');
    li.textContent = browser;
    fragment.appendChild(li);
});

element.appendChild(fragment);

자바스크립트에서 변수의 값을 조회하기 위해서는 어떻게 했지요? 네, 그냥 변수의 이름을 사용하면 조회할 수 있었습니다. 배열은 index를 조회했고, 객체는 key를 조회하면 됬었죠. 그렇다면 DOM은? 조금 특별한 방법을 사용해야 합니다.

HTML을 사용할 때, 가장 눈에 띄는 것이 무엇인가요? 네, tag와 id, class죠. 굳이 언급하지 않아도 우리는 눈으로 보고 이게 무엇인지 구분할 수 있습니다. (구분하지 못하신다면, HTML을 다시 공부하셔야겠군요!)

CSS 강의에서 배웠던 셀렉터(Selector)를 기억하시나요? 이 셀렉터를 활용하면 보다 효율적으로 DOM을 들여다볼 수 있습니다. querySelector 라는 녀석을 사용합시다. (querySelector는 한글로 셀렉터를 기반으로 한 질문을 한다, 쿼리를 날린다라는 의미입니다.) '.tweet' 을 첫 번째 인자로 넣으면 tweet을 클레스 이름으로 가진 모든 HTML 엘리먼트를 조회할 수 있습니다.

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

Index Collection
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections#Working_with_array-like_objects

Document.querySelector()
https://developer.mozilla.org/ko/docs/Web/API/Document/querySelector

ParentNode.append()
https://developer.mozilla.org/ko/docs/Web/API/ParentNode/append

뒤에다가 삽입 그러니까 마지막에 push 하는거랑 비슷

요소(element) 추가하기
var parent = document.createElement("div");
var p = document.createElement("p");
parent.append(p);

console.log(parent.childNodes); // NodeList [ <p> ]

ParentNode.prepend()
https://developer.mozilla.org/ko/docs/Web/API/ParentNode/prepend

이거는 맨앞줄에다가 넣어준다.


var parent = document.createElement("div");
var p = document.createElement("p");
var span = document.createElement("span");
parent.append(p);
parent.prepend(span);

console.log(parent.childNodes); // NodeList [ <span>, <p> ]
var parent = document.createElement("div");
parent.append("Some text");
parent.prepend("Headline: ");

console.log(parent.textContent); // "Headline: Some text"

Node.appendChild()
https://developer.mozilla.org/ko/docs/Web/API/Node/appendChild

difference between appendChild and append in javascript dom

append VS appendChild
https://dev.to/ibn_abubakre/append-vs-appendchild-a4m

https://ko.javascript.info/basic-dom-node-properties

https://www.w3schools.com/

https://indepth.dev/posts/1161/here-is-why-appendchild-moves-a-dom-node-between-parents

Element.setAttribute()
https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute

profile
임지택입니다.

0개의 댓글