[JavaScript] DOM

Steve·2021년 4월 26일
0

웹개발 코스

목록 보기
12/59

DOM : Document Object Model

Document(HTML)을 자바스크립트 객체(Object)처럼 조작할 수 있게 만든 것.
DOM 은 트리 자료구조를 가지고 있다.
Tree의 Root node는 document이다.

script 태그 위치에 따른 차이

  • 웹 브라우저는 <script> 요소를 만나면 HTML 해석을 멈추고 script 요소를 먼저 실행한다.
  • 스크립트를 먼저 실행하면 parse 되지 않은 HTML 요소를 query 했을 경우 null 이 된다. (C 로 치면 nullpointer, 즉 쓰레기값이다)

** parse - 해석하다

console.dir

console.dir(directory) 은 자바스크립트 오브젝트의 properties(특성) 리스트를 표시해준다.



DOM CRUD

CRUD : Create, Read, Update, Delete
( + APPEND)

node vs element

const object = document.querySelector('p');
object.nodeType; // Node.ELEMENT_NODE, 값은 1.

node 는 DOM 구성하는 객체이다. Element 는 node의 종류 중 하나이다.
node의 종류들. 마치 C의 enum 을 활용한 플래그와 비슷하다.

CREATE & APPEND

const myDiv = document.createElement('div'); // div 요소를 만든다.

// insert object after the last child of the Element.
document.body.append(myDiv); // body의 맨 마지막 자식 요소로 추가한다.

// insert object before the first child of the Element.
document.body.prepend(myDiv);

** append - (in writing) add it to the end of it.

createDocumentFragment()

DocumentFragment를 만들어 노드를 붙일 수 있다. 이 함수는 화면에 메모리에 존재하며 표시할 요소를 document 로 만든 뒤 한번에 DOM tree 에 append 할 수 있기 때문에 변화가 있을 때마다 매번 페이지에 반영하는 것보다 성능이 향상된다.

append vs appendChild (append가 newer API)

  • append는 문자열을 삽입할 수 있고, return value 가 없으며(appendChild는 append 한 노드를 반환), 여러개의 노드/문자열을 삽입할 수 있다.
  • node를 다른 부모로append할 경우 : clone 되지 않는다.


READ

document.body.children; // 자식 요소
querySelector('p').parentNode; // 부모 요소

// query 는 'question'의 뜻으로, 데이터를 조회하는 것을 말한다.
document.querySelector('tag'); // 이름이 일치하는 제일 첫 번째 요소를 반환한다.
element.querySelector('#id'); // 특정 element 내에서 찾는다.

// querySelectorAll : 여러개의 엘리먼트를 가져오며 배열처럼 사용할 수 있다.
querySelectorAll('.class');

// the OLD way (for old IE support)
getElementByTagName, getElementsByTagName
getElementByClassName, getElementsByClassName
getElementById

parentNode vs parentElement

작동은 거의 같으며, 다음과 같은 차이를 보인다.

document.documentElement.parentNode; // the document node
document.documentElement.parentElement; // null

childNodes vs children

childNode : node property. 여러 종류의 node 를 child node 로 가질 수 있다.
children : element property. children은 자식 element 만을 뜻한다.

예시:
<p>Hello world!</p> : <p>는 child node (text node) 를 가지고 있지만 children 은 없다.


UPDATE

// 요소에 텍스트 넣기
myDiv.textContent = '텍스트 넣기';

// 요소에 클래스 추가/제거하기
myDiv.classList.add('.some-style');
myDiv.classList.remove('.some-style');

// HTML 특성 추가/조회/삭제
myDiv.getAttribute('id');
myDiv.setAttribute('name', 'helloButton');
myDiv.removeAttribute('class');

textContent vs innerHTML (vs innerText, nodeValue)

<div id="test">
This element is <span style="display:none;">strong</span> and     has some super fun <code>code</code>!
</div>
// ---------------------------------------------------- //
const getValue = document.querySelector('#test');

getValue.textContent
// This element is strong and     has some super fun code!

getValue.innerText
// This element is and has some super fun code!

getValue.innerHTML
// This element is <span style="display:none;">strong</span> and     has some super fun <code>code</code>!

getValue.childNodes[0].nodeValue
// 노드의 값을 리턴. Element Node 는 null 을 리턴. HTML을 parse 하지 않음.
// This element is 

textContent : textContent의 값은 노드의 텍스트를 text/plain 으로 파싱(Parsing)한 결과이다. 즉, 해당 요소 내부의 원시 텍스트(raw text) 이다. 그래서 다른 프로퍼티들에 비해 파싱이 빠르다. 타입에 관해서는 MIME types | MDN

innerText : innerText 또한 텍스트를 text/plain 으로 파싱하지만, 최종적으로 화면에 보여지는 텍스트를 가진다. (style 태그를 활용한 스타일링, 줄바꿈 등은 표시되지 않음)

innerHTML : 데이터를 text/HTML 로 parse한다. 파싱이 느리다.
innerHTML 은 Cross-site Scripting(XSS)에 노출되어 있다.
XSS 는 클라이언트 사이드에서 코드를 심는 보안 공격이다. HTML5에서는 innerHTML과 함께 삽입된 <script> 태그가 실행되지 않도록 지정했지만, 여전히 다른 공격 루트들은 방어하지 못한다.

DELETE

myDiv.remove(); // 요소 삭제

// 반복문을 활용하여 요소 내의 모든 자식 요소 삭제 가능
const container = document.querySelector('#container');
while (container.firstChild) {
  container.removeChild(container.firstChild);
}

remove vs removeChild

  • 호출 대상이 다르다.

childElement.remove() // 자식 노드에 호출한다. 인자는 없다.
Element.removeChild(child) // 부모 노드에 호출한다. 인자는 자식 노드이다. 즉 참조 두개를 알아야 한다. 옛날 방식.
삭제 결과는 동일하며, 부모-자식 관계가 끊긴다. 오브젝트는 여전히 메모리에 남아 있으며, 제거하려면 garbage collector 가 제거해주거나, 수동으로 null 을 할당한다.

기타

좌표 정보 조회를 할 수 있다. - offsetTop...
크기 정보 조회를 할 수 있다. - offsetWidth..


느낀점

  • 정리하기엔 너무 많아서 '이런 것도 있구나' 정도로 마무리되는 것들이 있다. 이런게 존재하는지 알기만 해도 나중에 필요하면 써먹을 수 있으니 이득이다.
  • 그래도 정리를 하면서 몰랐던 것들을 엄청 많이 알게 되었다. 특히 비슷한 특성과 함수들이 너무 많아서 이것들을 비교하는데 시간이 많이 걸렸다. legacy 때문에 어쩔 수 없나보다.
  • 제때 정리를 안하면 힘들다는것을 느낀다. 그때그때 맞추어 공부하고 넘어가야 밀리지 않는다.
profile
게임과 프론트엔드에 관심이 많습니다.

0개의 댓글