토요일 이른 아침 부슬부슬 비가 내리고 있다. 요즘들어 늦게 잠이 들기 때문에 7시가 되어도 이른 아침의 피곤함을 느낀다. 하지만 오늘은 기대하던 DOM 사상을 배우는 날이라 아침까지 챙겨먹으며 몸단장하고 지하철에 올랐다. 주말이라서 사람들이 없어서 다행이다. 사람들이 눈을 감고 잠을 자는지 명상을 하는지 생각하고 있는 사이 가산 디지털단지에 도착. 창업진흥원을 찾아 20층에 올라왔다. 강의장은 아래 모습으로 마치 헤커톤에 온듯 자유로운 공간을 가지고 있다. 바로 앞에 사자머리 제임스 고슬링 코스프레 아저씨가 버티고 있어서 시야를 방해한다. 그래도 React가 Virtual DOM을 만들어 지원하고 있는데 DOM을 알 수 있다면 이쯤이야...
시작하기
"DOM은 사용자를 고려한다"
기술중심의 언어가 아닌 사용자 중심의 언어이다. DOM은 UI/UX를 제공하고 사용자의 접점이기 때문이다. 웹페이지 구성을 보면 HTML은 구조 CSS는 표현 DOM은 구조와 표현의 CRUD를 담당하고 통신은 HTTP, Socket, Ajax가 하고 Javascript는 컨트롤을 한다.
"DOM은 동적이다."
동적 페이지를 제공하고, UI(User Interface)는 사용자 행동, 시스템 응답 중심이라면 UX(User eXperience)는 사용자 경험, 습관, 관습 중심이며 이벤트(Event)는 사용자 행동 인식 및 요구/요청에 응답한다. 이 모든 것은 DOM 기본으로 알아야 이해할 수 있다.
"DOM은 도큐먼트로 작성한 것을 객체 개념으로 다양한 언어에서 접근토록 모델을 제공한다."
Document : "<!DOCTYPE html> ~ </html> 이 DOM 영역이다."
Object : 객체 개념으로 접근하고 객체 요소에는 행동과 속성이 있다. 이들은 key: value형태이다.
Model : 다수의 언어에서 사용하기 위해 Interface 행태로 DOM을 제공한다. DOMString 형태로 표기한다.
"Model을 바탕으로 Object를 만든다."
개발자 입장에서 중요한 것은 객체이고, 객체를 핸들링하는 것이다. 모델은 엔진이 사용해서 객체를 만들어 주는 시스템적인 것이다. Object로는 Document, Element, DOM Traversal, DOM/마우스/키보드/HTML/Mutation 이벤트, Selector, DOM View, CSSOM ( CSS Rule Set ) 등이다. 참조
DOM API/Level
"DOM의 기술적 의미는 API를 다루는 것이다."
DOM은 버전이라 하지않고 레벨이라 한다. DOM Level1은 마크업만 DOM Level2에서 CSS가 들어오고, 마우스 이벤트, DOM Traversal and Range가 들어옴. DOM 2부터 MS가 참여를 하지 않으므로 Cross Browsing 문제가 발생하기 시작한다. 관련된 iExplorer 버전은 6,7,8 이다. DOM 3는 XHTML 1.1 기준으로 나온다.
"DOM Level 1, 2, 3 에서 HTML 5 로 넘어왔다."
많은 이벤트 타입이 생기고, CSSOM (CSS Object Model) 분리가 된다. 예로 CSS, Media Query, Selector 등이다.
"HTML5의 핵심은 플랫폼이다."
오픈 플랫폼이며 표준을 바탕으로 하고, 최종 목적은 컨텐츠 제공이다. 브라우져 하나만 가지고 모든 것을 하겠다는 플랫폼의 의미가 들어왔다. 예로 Indexed DB 임베드. 네트워크가 끊어져도 작동을 할 수 있다. (스티브 잡스가 iPhone 4 발표때 HTML5를 이야기했다.)
"HTML5 분류는 마크업과 API이다."
마크업은 <video> <section>, 콘텐츠 모델이 새로 들어오고, <menu>, <i>, CSS 등이 재정이 된다.
API는 <canvas> <svg>로 직접 표현이 가능하고, Web Socket, IndexedDB등을 JS로 제어해 간접 표현이 가능하다.
* DOM 4는 HTML5 에서 분리되어 진행중이다.
DOM 구성 요소
"!doctype 최상위 요소 #document 이다."
Document -> Element -> Node
엘리먼트는 Element Interface를 Object로 생성한 것이다. 노드는 12개의 타입이 있다. 노드는 엘러멘트보다 더 작은 레벨이다. 노드도 오브젝트이다.
크롬 DevTools를 통해 head의 Node목록을 보면 엔터(enter) 키가 있는 text까지 해서 총 7개의 노드가 존재한다.
Document 객체의 속성을 살펴보자.
JS Bin on jsbin.com
- doctype
- implementation : 브라우저에서 지원하는 기능. 자바스크립트에서 사용할 일이 별로 없다.
document 메소드
getElemntsByName : 반환값 배열
JS Bin on jsbin.com
getElementsByTagName : 태그의 이름, 반환값 배열
getElementsByClassName : class 스타일 이름, 반환값 배열
getElementById : id 이름. DOM Tree에서 가장 먼저 나온 id의 값을 리턴함 (만일 id가 중복되어 있다면), 객체
createElement / createTextNode / createAttribute / createDocumentFragment / createRange / importNode / adoptNode ==> innerHTML 로 사용
Document Method-1 on jsbin.com
createAttribute
JS Bin on jsbin.com
Element
"엘리먼트 노드와 엘리먼트는 틀리다."
- 엘리먼트 노드 = <div id="sports">
- 엘리먼트 = <div> ~ </div>
"엘리먼트는 오브젝트 관점과 Data 관점으로 보아야 한다."
HTML은 오브젝트이고 데이터가 있다로 인식을 변환한다. (DOM Spec Element Interface), 엘러먼트(div)에는 기본 13개의 속성이 존재한다. 노드의 명칭(nodeName)은 일반적으로 #을 붙여준다. 예로 #document로 표현한다.
엘러먼트의 다양한 속성들 : nodeName, attributes와 classList 많이 사용한다. <!doctype> 때문에 tagName 대신 nodeName 을 사용한다.
Document Method-2 : createAttribute-2 on jsbin.com
"Element-client 는 CSS BoxModel과 관계한다."
clientHeight : scrollBar, border, margin을 미포함한다. 즉, 엘리먼트 높이와 padding만 포함.
clientWidth : 엘리먼트 넓이와 padding만 포함.
- Element Client
"CSS BoxModel은 margin padding border 이다."
Margin은 내집의 울타리 밖으로 다른 집과의 공통 구역. Padding은 내 울타리안이다. Border는 내 울타리의 넓이이다.
clientHeight, clientWidth, clientLeft, clientTop 예제
Element Client-1 on jsbin.com
- Element Offset
"offset은 엘리먼트가 부모와 떨어진 거리이다."
position 속성(absolute, relative, fixed, static)에 따라 부모와의 offset 값이 틀려진다. 예로 마우스 클릭의 좌표값을 구할 때 사용.
offsetHeight : 엘러먼트 높이 padding, scrollBar, baroder를 포함하고 margin 미포함 한다.
offsetParent는 CSS offset과 관련이 있고 DOM tree에서 가장 가까운 선조 엘리먼트이다. 항상 offsetParent와 offsetElement가 같지는 않음
- Element Scroll
scrollHeight : 엘리먼트 높이, padding 포함, scrollBar, border, margin 미포함
Element Scroll on jsbin.com
- Element Child, 그외 것들
childElementCount, childNodes : text 노드 포함 , children: text 노드 미포함 (Collection 타입)
childNodes는 7개이고 children은 3개이다. text는 엔터키 값을 갖는다.
Element Child on jsbin.com
- Element Text
innerHTML : 텍스트 형태를 HTML 형태로 자식으로 첨부. HTML5에서 표준이 되었다. DOM3에서 속도가 느렸으나 현재는 빠름
outerHTML : 텍스트 형태를 HTML 형태로 자신을 포함하여 대체한다. (주의)
Element 메소드
getAttribute, setAttribute, hasAttribute, removeAttribute (delete는 반환하는 엘러먼트가 없고 remove는 반환해 준다)
appendChild, removeChild, replaceChild, cloneNode, hasChildNodes
appendChild를 통해 전/후 위치이동 예제
Element Method on jsbin.com
* replaceChild는 사용하지 말고 가능한 removeChild 후에 appendChild로 호출해서 사용한다. 즉, 한꺼번에 두가지 기능을 하지 않게 한다.
* cloneNode는 노드의 모든 속성값을 가져옴. el.cloneNode(true);
DOM Traversal
DOM 트리 : DOM 노드가 구조적으로 연결한 형태
노드 : DOM 트리 구성 요소 (12개의 노드 타입) - DOM Spec Node Interface
인터페이스의 상수 값은 NodeType 이다.
"DOM Traversal은 이동은 Node 단위이다."
Node에는 text도 들어간다. 만일 node가 text이면 nodeType 값은 3 이다. node가 element이면 nodeType이 1 이다. DOM Traversal 프로퍼티인 firtNode, firstElementNode, lastChild, lastElementNode, nextSlibling, nextElementSlibling, previousSibling, previousElementSibling 을 이용해서 접근이 가능하다. 이대 *Element*가 붙으면 text노드를 제외한다.
하루 종일 DOM에 대해 목이 잠길 때까지 열정 강의를 해주신 김영보 선생님에게 감사하다. 내일이 기대된다.