자바스크립트 Dimension (Screen, Viewport, Scroll, Element, Mouse Event)



자바스크립트 Dimension



이번 포스트에서는 자바스크립트를 이용하여 DOM 상의 모든 위치값을 알아내는 여러 가지 방법에 대해 상세히 알아보도록 하겠습니다.


즉, 자바스크립트 Dimension에 관한 내용이며, 이는 자바스크립트 통한 DOM 조작 시 매우 많이 쓰이는 부분이기도 합니다.


관련 코드및 설명, 해당 영역에 대한 이미지는 아래와 같습니다.




1. Screen


  1. function _screen(){
  2.    
  3.     return {
  4.         w: screen.width,
  5.         h: screen.height
  6.     };
  7. };



Dimension.screen(): 사용자 디스플레이의 가로 / 세로 폭


- 모든 브라우저 지원


screen.width

screen.height











2. Viewport (page, window)


  1. function doc()
  2. {
  3.     var page = {
  4.        
  5.         w: top.window.scrollMaxX ? top.window.innerWidth + top.window.scrollMaxX : top.document.documentElement.scrollWidth || top.document.body.scrollWidth || 0,
  6.         h: top.window.scrollMaxY ? top.window.innerHeight + top.window.scrollMaxY : top.document.documentElement.scrollHeight || top.document.body.scrollHeight || 0
  7.     }
  8.      
  9.       , win = {
  10.  
  11.         w: top.window.innerWidth ? top.window.innerWidth : top.document.documentElement.clientWidth || top.document.body.clientWidth || 0,
  12.         h: top.window.innerHeight ? top.window.innerHeight : top.document.documentElement.clientHeight || top.document.body.clientHeight || 0
  13.     };
  14.  
  15.     return {
  16.         page: page,
  17.         win: win
  18.     };
  19. };



Dimension.doc().page: 스크롤 사이즈를 포함한 페이지 가로 / 세로 폭(ViewPort)


- 파이어 폭스만 지원


top.window.scrollMaxX: 스크롤 X 사이즈

top.window.scrollMaxY: 스크롤 Y 사이즈


top.window.innerWidth(사용자 가시폭(Dimension.doc().win.w)) + top.window.scrollMaxX:  문서의 전체 가로폭

top.window.innerHeight(사용자 가시폭(Dimension.doc().win.h)) + top.window.scrollMaxY  문서의 전체 세로폭



- 모든 브라우저 지원


top.document.documentElement.scrollWidth

top.document.documentElement.scrollWidth


top.document.body.scrollHeight

top.document.body.scrollHeight



Dimension.doc().win: 사용자의 가시폭



- IE9+ 및 표준 브라우저 지원


window.innerWidth 

window.innerHeight



- 모든 브라우저 지원


top.document.documentElement.clientWidth

top.document.documentElement.clientWidth


top.document.body.clientHeight

top.document.body.clientHeight






page:







window:












3. Scroll


  1. function scroll(){
  2.    
  3.     return {
  4.         x: top.window.scrollX || top.window.pageXOffset || top.document.documentElement.scrollLeft || top.document.body.scrollLeft || 0,
  5.         y: top.window.scrollY || top.window.pageYOffset || top.document.documentElement.scrollTop || top.document.body.scrollTop || 0
  6.     };
  7. };



Dimension.scroll(): 스크롤 X / Y 사이즈


- IE 브라우저를 제외한 브라우저 지원


top.window.scrollX

top.window.scrollY


top.window.pageXOffset

top.window.pageYOffset



- 모든 브라우저에서 지원


(DocType(문서타입)의 명시적 선언 유/무에 따라 document.body.scrollTop(Left) 반환 값이 달라짐. 

즉, DocType(문서타입)이 선언되지 않았을 경우는 document.body.scrollTop의 값을 정상적으로 반환하며, 반대의 경우에는 무조건 0을 반환합니다.)





top.document.documentElement.scrollLeft

top.document.body.scrollLeft


top.document.documentElement.scrollTop

top.document.body.scrollTop












4. Element


  1. function elem(elem){
  2.  
  3.     elem = elem || top.document.documentElement;
  4.  
  5.     var round = Math.round
  6.       , pFloat = parseFloat
  7.       , w = round(pFloat(Element.css(elem, 'width'))) || 0
  8.       , h = round(pFloat(Element.css(elem, 'height'))) || 0
  9.       , x = round(pFloat(getElementX(elem))) || 0
  10.       , y = round(pFloat(getElementY(elem))) || 0
  11.       , r = x + w || 0
  12.       , rx = round(pFloat(getParentRelativeX(elem))) || 0
  13.       , ry = round(pFloat(getParentRelativeY(elem))) || 0;
  14.  
  15.    
  16.     return {
  17.         w: w,
  18.         h: h,
  19.         x: x,
  20.         y: y,
  21.         r: r,
  22.         rx: rx,
  23.         ry: ry
  24.     };
  25. }
  26.  
  27.  
  28. function getElementX(elem){
  29.  
  30.     elem = elem || top.document.documentElement;
  31.     var x = 0;
  32.  
  33.     while (elem.offsetParent){
  34.        
  35.         x += elem.offsetLeft;
  36.  
  37.         elem = elem.offsetParent;
  38.     };
  39.  
  40.     return x;
  41. };
  42.  
  43. function getElementY(elem){
  44.  
  45.     elem = elem || top.document.documentElement;
  46.     var y = 0;
  47.  
  48.     while (elem.offsetParent){
  49.        
  50.         y += elem.offsetTop;
  51.  
  52.         elem = elem.offsetParent;
  53.     }
  54.  
  55.     return y;
  56. };
  57.  
  58. // 해당 엘리먼트와 직속 부모 엘리먼의 상대적인 X 위치
  59. function getParentRelativeX(elem){
  60.  
  61.     elem = elem || top.document.documentElement;
  62.  
  63.     return elem.parentNode === elem.offsetParent ? elem.offsetLeft :
  64.  
  65.     (getElementX(elem) - getElementX(elem.parentNode));
  66. };
  67.  
  68.  
  69. // 해당 엘리먼트와 직속 부모 엘리먼의 상대적인 Y 위치
  70. function getParentRelativeY(elem){
  71.  
  72.     elem = elem || top.document.documentElement;
  73.  
  74.     return elem.parentNode === elem.offsetParent ? elem.offsetTop :
  75.  
  76.     (getElementY(elem) - getElementY(elem.parentNode));
  77. };


Element.offsetParent: 


지정된 엘러먼트의 부모 엘리먼트를 가리킵니다.


단, 여기서 부모 엘리먼트들의 포지션이 상대(relative) 또는 절대(absolute) 포지션이 아니라면, .offsetParent 속성값은 무조건 document.body를 가리킵니다.









5. Mouse Event


  1. function mouse(e){
  2.    
  3.     e = top.window.event || e;
  4.  
  5.     var scroll = this.scroll();
  6.  
  7.     // x, y: 현재 마우스 위치
  8.     // rx, ry: 이벤트가 발생한 해당 엘리먼트와 마우스의 상대적인 x, y 위치
  9.     var x = e.pageX || e.clientX + scroll.x || 0
  10.       , y = e.pageY || e.clientY + scroll.y || 0
  11.       , rx = e.layerX || e.offsetX || 0
  12.       , ry = e.layerY || e.offsetY || 0;
  13.  
  14.  
  15.     return {
  16.         x: x,
  17.         y: y,
  18.         rx: rx,
  19.         ry: ry
  20.     };
  21. };


Dimension.mouse(e): 페이지의 현재 마우스 X / Y위치



- IE를 제외한 모든 표준 브라우저


e.pageX, e.pageY


- IE 브라우저


window.event.clientX + scroll.x(스크롤 X 사이즈)

window.event.clientY + scroll.y(스크롤 Y 사이즈)




이벤트가 발생한 엘리먼트와 마우스의 상대 X, Y 거리



- IE를 제외한 모든 표준 브라우저


e.layerX, e.layerY


- IE 브라우저


window.event.offsetX, window.event.offsetY















참고로 아래는 각 종 Dimension 수치를 볼 수 있는 페이지 입니다. 





http://13thparallel.com/archive/viewport/example6.htm