우리는 dom의 메서드나 속성에 대해서 잘알지 못하거나 애매하게 알고있다. react나 vue angular 혹은 이전엔 jquery의 도움을 받아 웹 개발을 했었기 때문이다. 때문에 dom에 대해 면밀히 파악해 볼겸 "DOM을 깨우치다" 를 읽어보며 헷갈릴만한 부분들을 정리해본다.
여러가지의 노드들로 구성되어 있다 여러가지 엘리먼트들로 구성되어있다~~ 이런식으로 말을 많이 한다.
결론만 말하면 element는 노드의 하위개념이다.
DOM과 Node
브라우저는 HTML코드를 해석해서 트리 형태로 구조화된 Node들을 가지고 있는 문서(DOM)을 생성한다.
DOM은 자바스크립트 Node개체의 계층화된 트리이다.
위 그림에서도 알 수 있듯이, 노드는 엘리먼트의 상위 개념이다. Element는 Node개체로부터 상속받은 하위 노드 개체이다. 그리고 Element 이외의 다른 개체들은 아래 표와 같이 볼 수 있다.
개체 | node type | example |
---|---|---|
HTML *Element | ELEMENT_NODE | <body> <a> |
Text | TEXT_NODE | 줄바꿈과 공백 포함한 html문서 내의 텍스트 문자 |
Attr | ATTRIBUTE_NODE | class="test" |
HTMLDocument | DOCUMENT_NODE | window.document |
DocumentFragment | DOCUMENT_FRAGMENT_NODE | document.createDocumentFragment() |
DocumentType | DOCUMENT_TYPE_NODE | <!DOCTYPE html> |
브라우저는 문서 초기 load시 html 문서 기반으로 노드 생성하긴 하나 아래와 같이 document 메서드를 사용해 직접 노드생성을 해주거나, 문자열을 하여 생성 해주는 방법이 있다.
document 메서드 사용
또한 아래와 같이 문자열을 삽입 해서도 가능하다.
문자열을 사용하여 DOM에 엘리먼트 및 텍스트 노드 생성 및 추가
innerHTML
outerHTML
textContext
insertAdjacentHTML()
위 두개가 헷갈렸는데 아래와 같은 차이점이 있다.
innerHTML 은 요소 안의 모든 태그들이 교체되는 것이고
appendChild 는 요소 안의 태그들은 그대로 두고 맨 뒤에 추가되는 것이다.
var divA = document.getElementById("A");
divA.parentNode.removeChild(divA);
var divA = document.getElementById("A");
var newSapn = document.createElement("span");
divA.parentNode.replaceChild(newSpan, divA);
제거하거나 바꾸는 대상이 무엇인지에 따라 innerHTML, outerHTML, textContent속성에 빈 문자열을 주는것이 더 쉽고 빠를수도 있다. 하지만 존재하지 않는 요소에 값을 할당하지 않는것이므로, 브라우저의 메모리 누수가 발생할수 있으므로 조심해야 한다고 한다.
HTMLCollection과 NodeList는 유사배열이라는 공통점이 있지만 생성하는 메서드도 다르며 조금씩 차이는 있다.
HTMLCollection
위 메서드들로 생성 가능
NodeList
element.childNodes
프로퍼티나 document.querySelectorAll
메서드로 반환되는 노드의 모음이다. NodeList
도 유사 배열인데, forEach
메서드는 가지고 있다. 하지만 browser support는 확인이 필요하다. 또 다른 이용 가능한 메서드에는 entries()
, keys()
, values()
가 있다.
유사배열에서 배열메소드 사용하기
Array.prototype.forEach.call(nodeList, function(node) {
// Your code here.
});
map
, filter
등의 메서드를 유사배열에서 사용하려면 위에서 언급한 방법을 이용해 배열로 바꿔주어야 한다.
문서내에서 포커스를 가지고 있거나 활성상태인 노드에 대한 참조
문서 혹은 문서 내의 특정 노드가 포커스를 가지고 있는지 판별하기
setInterval(function() {
console.log(document.hasFocus());
}, 1000);
document.querySelector("content").children[4].scrollIntoView(true);
getComputedStyle 은 element의 계산된 스타일 (계층화된것을 포함한 실제스타일)을 가져옴
아래 예제에서 볼수 있음.