블로그 이미지
윤영식
Frontend Application Architecter, Full Stacker, KnowHow Dispenser and Bike Rider

Publication

Statistics Graph

Recent Comment

2015.09.06 15:29 HTML5, CSS3

피곤할 때는 술 한잔을 하고 자면 풀릴까 하고 두잔을 하고 잤더니 피곤이 풀리기는 커녕 눈꺼풀만 무겁다. 7시 알람이 휴대폰에서 요란하게 울리지만 20분을 뒤척인 끝에 DOM생각에 벌떡 일어나 냉동실에 얼려 놓은 찹쌀떡을 하나 먹고 길을 나썼다. 관악산의 산바람이 시원하게 얼굴을 스치고 반바지 아래로 차가움이 감싼다. 2일차 DOM강의실로 삼양 컵라면 하나를 들고와서 따끈한 국물을 마시고 손놀릴 준비를 한다. 





Event


"다큐멘트에서 발생하는 이벤트를 설정하고 작용한다."

이벤트 설정에는 이벤트 타입이 있다. 이벤트 처리는 핸들러/리스너라 부르지만 리스너가 표준(스펙)용어이다. 캡쳐/버블은 DOM Tree와 관련이 있다. 이벤트의 버블링은 document 밑의 html 객체까지 올라간다. 기본이 이벤트 전파이기 때문에 적절히 방지를 해주어야 한다. 


"스펙을 보자. 이벤트 스펙"

이벤트 전체 스펙을 읽어보자 

Target : 이벤트가 발생한 곳

1, 2, 3 : 이벤트의 발생 Phase



"캡쳐, 버블링"

window부터 캡쳐링 된다. DOM의 path구조를 메모리상에 만들어 놓고 캡쳐/버블링 phase로 찾아간다. 예로 아래와 같이 파란색의 tr을 클릭하면 먼저 밑으로 간 후 위쪽으로 버블링된다. 3번의 버블링은 막을 수 있지만 1번 단계는 막을 수 없다. 왜 버블링을 발생하고 막게 할 수 있을까?


 

                                         그림에 대한 참조 사이트


"이벤트 설정은 element.addEventListener() 이다."

버블/캡쳐가 기본이고 캡쳐링은 모든 리스너가 무시(false) 한다. IE 6,7,8은 attachEvent() 이고 파라미터가 2개이다. 그리고 IE 6,7,8에서는 캡쳐/버블링을 하지 않는다. HTML5는 on을 넣어 이벤트 리스너를 표현한다. 예) onclick


"이벤트 리스너 사용 예제"

clickNode.addEventListener('click', handleClick, false); 소스에서 세번째 파라미터가 false 이면 버블링을 리스너가 처리하고 true이면 캡쳐링을 리스너가 처리한다. 전파(propagation)에 대해 버블링 막기는 event.stopPropagation() 호출한다. 태그에 할당된 이벤트를 막기위해 예로 <a> 태그의 화면 이동을 막기위해 event.preventDefault() 호출한다. 

DOM Event on jsbin.com 


"이벤트 해제"

이벤트 타입과 핸들러까지 해제를 해준다. 즉, 해제시 이벤트 설정과 파라미터를 같게 설정한다. element.removeEventListener, (IE, element.detachEvent)

DOM - Remove Event on jsbin.com


"메모리 누수"

설정한 이벤트를 해제하지 않았을 때 발생한다. unload 이벤트가 발생했을 때 일괄 해제한다. 설정한 이벤트 인식이 필요하다. 이벤트 설정 내역을 별도로 저장한다. 


"리스너 작성 형태"

엘리먼트에 onclick과 같이 작성할 수 있게 HTML5에서 채택함. <input type="button" onclick="handler()"> 이런 형태는 구조와 제어가 혼합되므로 비추! .js파일을 별도로 작성하여 구조와 제어를 분리한다. 

DOM onclick on jsbin.com


"버블링" 

세번째 파라미터가 false 버블링시에 핸들러 작동하고, true이면 캡쳐링시에 핸들러가 작동한다. true, false를 바꾸어 swim을 클릭하면 실행해 보면 캡쳐링할 때는 sports -> swim으로 찍히고 버블링시에는 swim -> sports가 찍힌다. 

JS Bin on jsbin.com


"버블링 방지" 

전파(propagation)에 대한 방지는 버블링시에 가능하고, 캡쳐링시에는 불가능하다. 

JS Bin on jsbin.com


"디폴트 액션 방지"

preventDefault() 호출. IE 경우는 event.returnValue=false로 설정한다. 이벤트 리스너를 설정하면 헨들러가 먼저 동작하므로 디폴트 액션을 막을 수 있다. 

JS Bin on jsbin.com


"이벤트 속성"

type

target : 이벤트를 설정한 엘리먼트 

currentTarget : 버블링 되면 버블링 엘리먼트로 변경 설정됨 





마우스 이벤트


"마우스 이벤트"

UX적으로 더블클릭은 제외시킨다. click은 mouseup, mousedown을 포함한다. 모바일에서는 mousemove를 쓰지말고 touchmove를 통해 하고 움직일때 x/y 좌표값을 계산하는 DOM parsing을 하지 않도록 프로퍼티를 먼저 설정해준다. 사용자의 베터리를 절약해 줘야 한다. 

mousedown -> mouseup -> click 순으로 발생한다. 

DOM Mouse Event on jsbin.com


"마우스 이벤트 프로퍼티"

altKey, ctrlKey, shiftKey, screenX/Y, clientX/Y

DOM Mouse Event Properties on jsbin.com


"마우스 over, out 이벤트는 어디서 들어왔는지 어디로 나갔는지가 중요하다"

어디는 relatedTarget 이다. margin: 20px의 영역은 마우스 over, out에서 제외된다. 즉, 나의 영역이 아니다. 

JS Bin on jsbin.com


"keypress는 되도록 사용하지 말라"

keydown, keyup 에서 input 태그에서 추천단어(suggest)를 보여주려고 할때는 keydown시 계속 누를 수 있으므로 keyup을 잡아준다. Firefox의 한글 사용 경우는 spacebar넣어야 suggest가 된다. keypress는 keydown <-> keyup 사이에 발생한다. 이를 이용해서 Firefox의 제약을 해결할 수 있다. 


"HTML 이벤트"

focus, blur, change, select, load (렌더링되면), unload (브라우저 닫을경우), resize, scroll, reset (form), submit (form)

DOMContentLoaded가 먼저 수행되어 DOM 객체 Tree 구조를 만들어 놓고, 다음으로 img 태그같은 이미지불러오기도 다 끝나면 onload가 불려지고, 다음으로 자바스크립트를 수행한다. 

JS Bin on jsbin.com

 




Mutation 이벤트


이벤트 타입: DOMNodeInserted, DOMNodeRemoved, DOMAttrModified...

해당 이벤트는 새로운 프로젝트에서 사용하지 말라. (MDN 참조) 속성값이 변한것을 인식해야 할 경우 DOMAttrModified 이벤트 타입을 사용할 수 있다. 

DOM Mutation Event on jsbin.com


신고
posted by peter yun 윤영식
2015.09.05 17:54 HTML5, CSS3

토요일 이른 아침 부슬부슬 비가 내리고 있다. 요즘들어 늦게 잠이 들기 때문에 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, attributesclassList 많이 사용한다. <!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에 대해 목이 잠길 때까지 열정 강의를 해주신 김영보 선생님에게 감사하다. 내일이 기대된다. 


신고
posted by peter yun 윤영식
prev 1 next