본 포스팅은 여기에 올라온 게시글을 바탕으로 작성되었습니다.
파트와 카테고리 동일한 순서로 모든 내용을 소개하는 것이 아닌, 몰랐거나 새로운 내용 위주로 다시 정리하여 개인공부 목적으로 작성합니다.
중간중간 개인 판단 하에 필요하다고 생각될 시, 기존 내용에 추가로 보충되는 내용이 있을 수 있습니다.
자바스크립트는 요소의 너비나 높이 같은 기하 정보 관련 프로퍼티를 지원한다. 이런 프로퍼티는 요소를 움직이거나 특정 좌표에 위치시킬 때 사용할 수 있다.
해당 프로퍼티 사용법을 알아보기 위해 하나의 샘플요소를 만들어보자.
<div id="example">
...텍스트...
</div>
<style>
#example {
width: 300px;
height: 200px;
border: 25px solid #E8C48F;
padding: 20px;
overflow: auto;
}
</style>
이로 인해 만들어지는 UI는 아래와 같다.
스크롤바가 생기게 되면 브라우저마다 그 처리가 조금씩 상이하다. 몇몇 브라우저는 콘텐츠 영역 너비 일부를 빌려 스크롤바를 위치시키기 때문이다. 샘플 예시에서도 만약 스크롤바가 없었다면 너비는 300px
이었을 것이다. 하지만 스크롤바가 16px
을 차지하기 때문에 콘텐츠 영역 너비가 284px
로 재조정된 것을 알 수 있다.
기하 프로퍼티를 그림으로 나타내면 다음과 같다.
기하 프로퍼티의 값은 숫자인데, 그 단위는 픽셀이다. 따라서 기하 프로퍼티는 모두 픽셀 단위로 측정된다. 요소 밖에서부터 안으로 기하 프로퍼티의 세부사항을 살펴보도록 하자.
잘 쓰이는 프로퍼티는 아니지만 가장 바깥에 위치한 기하 프로퍼티이다. 여기서 사용되는 offset
이라는 용어의 기본적인 의미는 요소가 화면에서 차지하는 영역 전체 크기를 나타내는데, 요소의 너비와 높이에 패딩,스크롤바, 테두리를 합친 크기이며 이때 마진은 포함되지 않는다.
offsetParent
프로퍼티는 해당 요소를 렌더링할 때 좌표 계산에 사용되는 가장 가까운 조상 요소의 참조를 반환한다. 조상 요소는 CSS position
에 영향을 받기 때문에 반환되는 가장 가까운 조상 요소는 아래 셋 중 하나에 해당한다.
position
프로퍼티가 absolute
, relative
, fixed
, sticky
인 가장 가까운 조상 요소<td>
, <th>
또는 <table>
<body>
offsetLeft
와 offsetTop
프로퍼티는 offsetParent
를 기준으로 각각 요소가 오른쪽, 그리고 아래쪽으로 얼마나 떨어져 있는지 나타낸다.
아래 예시에서는 offsetParent
는 <main>
태그이고 offsetLeft
와 offsetTop
은 각각 180px
이다.
<main style="position: relative" id="main">
<article>
<div id="example" style="position: absolute; left: 180px; top: 180px">...</div>
</article>
</main>
<script>
alert(example.offsetParent.id); // main
// (주의: 문자열 '180px'이 아닌 숫자 180이 반환)
alert(example.offsetLeft); // 180
alert(example.offsetTop); // 180
</script>
다음과 같은 요소를 기준으로는 offsetParent
가 null
이 될 수도 있다.
display
프로퍼티가 none
이거나 문서 내에 있지 않은 요소)<body>
와 <html>
position
프로퍼티가 fixed
인 경우offsetWidth
와 offsetHeight
는 가장 간단한 프로퍼티이며, 각각 요소의 가장 바깥 부분이 차지하는 너비와 높이를 제공한다. 즉 테두리를 포함한 요소 전체의 사이즈 정보를 제공한다.
샘플 요소를 대상으로 offsetWidth
와 offsetHeight
를 계산하면 다음과 같다.
offsetWidth = 390
: 컨텐츠 너비(300
) + 테두리 너비(25 * 2
) + 패딩 너비(20 * 2
)offsetHeight = 290
: 컨텐츠 높이(200
) + 테두리 너비(25 * 2
) + 패딩 너비(20 * 2
)이때 화면에 표시되지 않는 요소의 기하 프로퍼티 값은 0
또는 null
이다. 기하 프로퍼티는 항상 보이는 요소를 대상으로만 계산된다. 따라서 요소 혹은 이 요소의 조상 요소 중 어떤 것이든 화면에 표시되지 않는다면 모든 기하 프로퍼티의 값은 0이 된다. (offsetParent
프로퍼티는 null
)
요소를 만들기는 했지만 아직 문서에 삽입하지 않았다던지, 아니면 새롭게 만든 요소가 숨겨져 있다면 기하 프로퍼티의 값은 0과 같다. 이러한 특징을 이용하면 요소의 숨김 상태 여부를 아래와 같은 방법으로 확인할 수 있다.
function isHidden(elem) {
return !elem.offsetWidth && !elem.offsetHeight;
}
그런데 isHidden
함수는 요소가 화면에 있기는 하지만 사이즈가 0일때 (비어있는 <div>
등) 역시 true
를 반환한다는 점을 주의해야 한다.
마진(margin
)과 달리 테두리(border
)는 요소 내에 존재한다. 이때 clientTop
과 clientLeft
를 사용하면 테두리의 두께를 측정할 수 있다. 샘플 예시에서 테두리 두계를 계산하면 다음과 같다.
clientTop = 25
: 위쪽 테두리 높이clientLeft = 25
: 왼쪽 테두리 너비하지만 clientTop
과 clientLeft
프로퍼티는 특정 경우에 테두리 높이와 너비와 정확하게 일치하지 않을 수 있다. 이는 사실 엄밀히 말하면 테두리 바깥을 기준으로 한 테두리 안 상대좌표를 나타낸다.
예를 들어 아랍어나 히브리어의 경우에서는 글이 오른쪽에서 왼쪽으로 전개된다. 따라서 이에 따라 스크롤바 역시 대부분 언어와는 달리 왼쪽에 배치가 되는데, 이 경우에는 clientLeft
에 스크롤바 너비가 포함된다.
위 그림처럼 이 경우엔 clientLeft
는 기존 25
에 스크롤 너비 16
을 더한 41
이 된다.
clientWidth
와 clientHeight
프로퍼티는 테두리 안 영역의 사이즈 정보를 제공한다. 테두리 안에는 콘텐츠 너비와 패딩이 포함되는데 이때 스크롤바 너비는 포함되지 않는다.
먼저 clientHeight
의 경우에는 가로 스크롤바가 없기 때문에 테두리 안 영역 전체를 더한 값이 된다. 이는 요소 자체의 높이 200px
과 패딩으로 지정된 20px * 2 = 40px
의 합으로 총 240px
이 된다.
clientWidth
의 경우에는 세로 스크롤바로 인해 콘텐츠 너비에 변경이 생긴다. 처음 설정된 콘텐츠 너비는 300px
로 지정되었으나 스크롤바의 너비 16px
은 제외하기 때문에 이는 284px
로 계산된다. 위와 마찬가지로 패딩값을 더한 최종 값은 총 324px
이 된다.
따라서 패딩이 없는 경우에 clientWidth
와 clientHeight
는 테두리와 스크롤바 안쪽에 있는 콘텐츠 영역의 너비 및 높이와 정확히 일치할 것이다.
scrollWidth
와 scrollHeight
프로퍼티는 clientWidth
와 clientHeight
유사한데, 스크롤바에 의해 감춰진 영역까지 모두 포함한다는 점에서 차이가 있다.
scrollWidth = 324
: 수평 스크롤바가 없기에 clientWidth
와 동일scrollHeight = 723
: 세로 스크롤바에 가려진 부분 모두 포함하는 콘첸트 영역 안쪽 전체의 높이이러한 특성을 통해 scrollWidth
와 scrollHeight
는 요소 크기를 콘텐츠가 차지하는 만큼 늘리고자 할 때 사용할 수 있다.
elem.style.height = `${elem.scrollHeight}px`;
scrollLeft
와 scrollTop
은 가로 스크롤이 오른쪽, 세로 스크롤이 아래로 움직임에 따라 가려진 영역의 너비와 높이를 나타낸다.
세로 스크롤바를 아래로 조금 내린 경우를 가정한 그림을 살펴보자. 이때 scrollHeight
에서 scrollTop
이 얼마만큼의 영역을 차지하는지 볼 수 있다.
이처럼 scrollTop
은 세로 스크롤바에 의해 가려져 보이지 않는 위쪽 콘텐츠의 높이를 말한다.
또 하나 특이한 점은 대부분의 기하 프로퍼티가 읽기 전용인 반면 scrollLeft
와 scrollTop
의 경우 변경이 가능하다는 점이다. 스크립트로 이 값을 조정하면 자동으로 요소 내 스크롤 위치가 변하게 된다. 이를 통해 브라우저의 스크롤 위치를 맨위 또는 맨아래 등으로 옮기는 등의 작업 또한 가능하다.
기하 프로퍼티를 이용하면 컨텐츠 영역을 포함한 요소의 사이즈를 얻을 수 있다. 그러나 우리는 이전 챕터에서 getCouputedStyle
메서드를 사용해 CSS가 적용된 요소의 높이와 너비를 구할 수 있음을 살펴보았다. 하지만 CSS를 사용해 너비와 높이에 접근하는 것은 추천하지 않는다.
먼저 CSS width
와 height
는 다른 CSS 프로퍼의 영향을 받는다. 요소 너비와 높이 계산 방법을 지정하는 box-sizing
이 대표적인 예시인데, 따라서 box-sizing
이 변경되면 getCouputedStyle
을 통해 구한 값이 부정확해질 수 있다.
또한 CSS width
와 height
는 auto
일 수 있다. 이 경우 화면에 보여지는 요소의 사이즈는 픽셀 단위로 부여되어 있지만 getCouputedStyle
을 통해 구해오는 값은 auto
가 되기 때문에 픽셀 단위의 숫자값을 구할 수 없다.
또 다른 이유는 스크롤바의 유무이다. 스크롤바가 없다면 정상적으로 동작하는데, 만약 스크롤바가 생기게 되면 의도한 대로 동작하지 않을 수 있다. 스크롤바가 있는 경우 getCouputedStyle
을 통해 너비와 높이를 구할 때는 브라우저마다 상이한 결과를 출력한다. 크롬 브라우저의 경우에는 스크롤바 너비를 제외한 진짜 내부 너비를 반환하지만, 파이어폭스 브라우저의 경우에는 스크롤바를 무시하고 CSS로 설정한 너비를 반환한다. 이렇게 브라우저 간 차이로 서로 다른 값을 출력하기 때문에 일정한 값을 보장하는 기하 프로퍼티로 접근하는 것이 권장된다.
브라우저 창이 차지하는 너비와 높이는 어떻게 구할 수 있을까? 스크롤 때문에 보이지 않는 영역을 포함해 문서 전체가 차지하는 너비와 높이에 대한 수요가 있을 수 있다. 이때 자바스크립트를 사용해 페이지를 스크롤 할 수 있을까?
이번 챕터에서는 루트 문서 요소인 document.documentElement(= <html>)
에서 지원하는 프로퍼티와 메서드를 살펴보도록 하자.
창이 차지하는 너비와 높이를 알기 위해서는 document.documentElement
의 clientWidth
와 clientHeight
를 사용하면 된다.
이때 window
객체가 아닌 document.documentElement
를 사용하는 이유가 있다. window
객체는 브라우저 호스트 환경에서 최상단에 위치한 루트 객체이고, 해당 객체에서도 innerWidth
와 innerHeight
를 제공하기 때문에 이를 사용해서 창 크기에 접근할 수 있다.
하지만 스크롤바가 생기는 경우엔 앞서 살펴본 바와 같이 clientWidth
와 clientHeight
는 스크롤바가 차지하는 공간을 제외하여 너비와 높이를 계산한다. 따라서 눈에 보이는 문서에서 콘텐츠가 실제 들어가게 될 영역 너비와 높이 값을 계산한다.
그러나 window.inner...
프로퍼티의 경우에는 스크롤바가 차지하는 영역을 포함해 값을 계산한다. 따라서 스크롤바가 있는 경우엔 실제 콘텐츠 영역이 차지하는 사이즈와 다른 값을 가지게 된다. 보통 창 사이즈가 필요한 경우엔 스크롤 바 안쪽에 무언가를 배치하거나 그리는 경우가 많기 때문에, 창 크기를 구하는 목적이 이와 부합한다면 document.documentElement
를 사용하는 것이 좋다.
기하 관련 프로퍼티는
DOCTYPE
이 명시되어 있지 않은 경우 제대로 동작하지 않는 경우가 있다. 따라서 항상 HTML 문서에 이를 정의해주는 것이 필요하다.
이론상 document.documentElement
는 문서의 루트 요소에 상응하고 루트 요소엔 콘텐츠 전부가 들어가기 때문에 문서 전체 크기는 document.documentElement
의 scrollHeight
와 scrollWidth
를 사용하면 구할 수 있을 것으로 보인다.
그런데 전체 페이지를 대상으로 했을 때 document.documentElement
프로퍼티는 간혹 예상과는 다르게 동작할 때가 있다. 크롬, 사파리, 오페라에서 스크롤이 없는 경우에는 document.documentElement.scrollHeight
가 document.documentElement.scrollWidth
보다 작은 경우가 종종 발생한다. 같은 값이어야 함에도 불구하고 미세한 차이가 있을 때가 있다.
따라서 정확한 문서 전체 높이 값을 얻으려면 아래 여섯 프로퍼티가 반환하는 값 중에 최댓값을 구해야 한다.
let scrollHeight = Math.max(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight
);
DOM
요소의 현재 스크롤 상태(스크롤에 의해 가려진 영역에 대한 정보)는 scrollLeft
와 scrollTop
프로퍼티를 통해 구할 수 있다.
대부분의 브라우저에서 문서의 스크롤 상태는 document.documentElement
의 scrollLeft
또는 scrollTop
을 이용해 구할 수 있다. 다만 구버전 Webkit
을 기반으로 하는 브라우저에서는 버그 때문에 documet.documentElement
가 아닌 document.body
를 사용해야 원하는 값을 구할 수 있다.
따라서 스크롤 포지션 정보를 위해 브라우저별 예외처리까지 모두 고려해야 하는 생각이 들 수 있다. 그러나 다행히 window
객체에서 제공하는 pageXOffset
과 pageYOffset
을 사용하면 브라우저 상관없이 스크롤 정보를 구할 수 있다.
alert('세로 스크롤에 의해 가려진 위쪽 영역 높이: ' + window.pageYOffset);
alert('가로 스크롤에 의해 가려진 왼쪽 영역 너비: ' + window.pageXOffset);
다음 메서드를 사용하기 위해선 한 가지 전제 조건이 필요하다. 자바스크립트를 사용해 스크롤을 움직이려면 DOM
이 완전히 만들어진 이후에 적용되어야 한다.
일반 요소의 스크롤 상태는 scrollTop
이나 scrollLeft
로 쉽게 변경할 수 있다. 페이지 전체의 스크롤 상태 역시 document.documentElement
의 scrollTop/scrollLeft
를 사용해 변경할 수 있다.
다만 사파리의 경우에는
document.body
의scrollTop/scrollLeft
를 사용해야 한다.
그러나 이보다 더 편하고 브라우저 상관없이 쓸 수 있는 대안이 있다. 위에서 언급한 바와 마찬가지로 브라우저 호스트 환경의 최상단 객체인 window
객체를 이용하는 것이다. window
객체에서는 다음 두 가지 메서드를 제공한다.
window.scrollBy(x, y)
scrollBy(0, 10)
을 호출하면 문서의 스크롤 상태를 현재를 기준으로 아래로 10px
내린 것처럼 동작한다window.scrollTo(pageX, pageY)
(pageX, pageY)
가 된다.scrollLeft/scrollTop
값을 변경한 것 처럼 이동scrollBy(0, 0)
을 호출하면 스크롤 상태를 처음 상태로 이동elem.scrollIntoView(top)
을 호출하면 전체 페이지 스크롤이 움직여 elem
요소가 눈에 보이는 상태로 변경된다. 이때 사용되는 매개변수는 Boolean
값을 받는데 이에 따라 다른 동작을 보여준다.
top = true
: 디폴트 값이며, elem
이 페이지에 가장 상단에 보이도록 스크롤 상태 변경top = false
: elem
이 페이지 가장 하단에 보이도록 스크롤 상태 변경때에 따라 문서의 스크롤바를 고정해두고 조작이 불가능하도록 막아야 할 경우가 생길 수 있다. 사용자가 반드시 읽어야 하는 메시지를 노출시켜야 하는 경우 또는 모달 창이 뜨는 경우 등이 그러한 경우이다.
이럴 때 단순하게 document.body.style.overflow = 'hidden'
을 사용할 수 있다. 이는 화면에 보이는 영역을 넘어가는 부분은 모두 숨김처리를 함으로써 스크롤바를 없애는 기법이다. 스크롤바가 제거되기 때문에 당연히 스크롤 이동을 막을 수 있다. DOM
객체 프로퍼티 중 style
을 조정하는 것이기 때문에 document.body
뿐만이 아니라 다른 요소에도 동일하게 적용할 수 있다.
하지만 이 방법은 스크롤바가 사라지기 때문에 해당 공간을 채우기 위해서 기존 콘텐츠의 위치가 재조정될 수 있다. 이 경우에는 모든 콘텐츠의 위치가 조금씩 바뀌면서 갑자기 움직이는 현상이 보인다. 이러한 현상은 사용자의 UX를 해칠 수 있다.
따라서 개발자는 스크롤바를 고정시키기 전과 후의 clientWidth
값을 비교해서 해당 증상을 보정해야 한다. 스크롤바가 사라질 때 clientWidth
값이 커지는데 이때 스크롤바가 차지했던 영역만큼 document.body
에 padding
을 주는 등의 기법으로 콘텐츠 전체의 너비를 스크롤바가 사라지기 전과 같은 값으로 유지할 수 있다.
앞서서 요소의 크기와 스크롤 바를 이동시키는 방법들을 살펴보며 몇몇 메서드에서는 좌표(coordinates
)가 사용되는 것을 볼 수 있었다. 따라서 요소를 움직이기 위해서는 좌표에 대해 익숙해져야 한다.
자바스크립트에서 메서드는 다음 두 좌표 체계 중 하나를 이용한다.
position: fixed
와 유사하게 창(window) 맨 위 왼쪽 모서리를 기준으로 좌표 계산clientX/clientY
로 표시position: absolute
를 사용하는 것과 비슷하게 문서 맨 위 왼쪽 모서리를 기준으로 좌표 계산pageX/pageY
로 표시스크롤을 움직이기 전에는 창의 맨 왼쪽 모서리가 문서의 맨 위 왼쪽 모서리와 정확히 일치한다. 그런데 스크롤이 움직이면서 문서가 이동하면 문서 기준 좌표는 변경되지 않지만, 창 내의 요소는 움직이기 때문에 창 기준 요소 좌표가 변경된다.
pageY
: 문서 기준 좌표는 문서 맨 위부터 계산되므로 스크롤 전후 값이 동일clientY
: 문서가 스크롤 되면서 해당 지점이 창 상단과 가까워 졌기 때문에 좌표 변동 발생elem.getBoundingClientRect()
메서드는 elem
을 감싸는 가장 작은 네모의 창 기준 좌표를 DOMRect
클래스의 객체 형태로 반환한다.
DOMRect
의 주요 프로퍼티는 다음과 같다.
x
와 y
: 요소를 감싸는 네모의 창 기준 X,Y 좌표width
와 height
: 요소를 감싸는 네모의 너비, 높이(음수도 가능)top
과 bottom
: 요소를 감싸는 네모의 위쪽 모서리, 아래쪽 모서리의 Y 좌표left
와 right
: 요소를 감싸는 네모의 왼쪽 모서리, 오른쪽 모서리의 X 좌표그림을 통해 x
, y
, width
, height
만으로 네모 영역을 완전히 묘사할 수 있다는 점을 알 수 있다.
elem.getBoundingClientRect()
를 사용할 때 주의사항은 다음과 같다.
10.5
처럼 소수일 수 있다. 브라우저는 좌표 계산에 소수를 사용하기 때문에 이는 정상이다. 따라서 style.left/top
을 사용할 때 값을 반올림할 필요가 없다.elem
이 창 위로 밀려났을 때 elem.getBoundingClientRect().top
은 음수가 된다.
right
,bottom
좌표는CSS position
스타일 속성과 다르다. 위 그림을 보면 그 차이를 한 눈에 알 수 있는데,CSS position
의 경우는right
가 오른쪽으로 부터의 거리를 말하는 반면 좌표에서의right
는 항상 왼쪽 위 모서리를 기준으로 떨어진 거리를 말한다.
document.elementFromPoint(x, y)
를 호출하면 창 기준 좌표 (x, y)
에서 가장 가까운 중첩 요소를 반환한다.
아래 예시를 실행하면 창 정중앙에 있는 요소의 태그가 붉은색으로 변하는 것을 볼 수 있다. 이때 창 정중앙에 있는 요소는 현재 스크롤 위치에 따라 달라질 수 있다.
let centerX = document.documentElement.clientWidth / 2;
let centerY = document.documentElement.clientHeight / 2;
let elem = document.elementFromPoint(centerX, centerY);
elem.style.background = 'red';
이때 창 밖에 있는 좌표를 대상으로 elementFromPoint
를 호출하면 null
이 반환된다. 해당 메서드는 항상 (x,y)
가 보이는 영역 안에 있을 때만 동작한다.
좌표는 대부분 무언가를 위치시키려는 목적으로 사용한다. 요소 근처에 무언가를 표시할 때엔 getBoundingClientRect
를 사용해 요소의 좌표를 얻고 CSS position
을 left/top/right/bottom
과 함께 사용해서 표시할 수 있다.
let elem = document.getElementById("coords-show-mark");
function createMessageUnder(elem, html) {
// 메시지가 담길 요소를 생성
let message = document.createElement('div');
message.style.cssText = "position:fixed; color: red";
// 좌표 지정 : style 프로퍼티는 px가 함께 기재된 문자열을 입력받음
let coords = elem.getBoundingClientRect();
message.style.left = coords.left + "px";
message.style.top = coords.bottom + "px";
message.innerHTML = html;
return message;
}
let message = createMessageUnder(elem, 'hello World!');
document.body.append(message);
setTimeout(() => message.remove(), 5000);
위 예시를 실행시키면 페이지 내에 id="coords-show-mark"
속성을 가지고 있는 HTML 요소가 있다면 그 하단 부에 hello World!
텍스트가 5초간 출력되는 것을 확인할 수 있다.
하지만 이때 스크롤을 하게 되면 메시지가 요소와 떨어지는 것을 볼 수 있다. 왜냐하면 메시지 요소가 position: fixed
이기 때문에 페이지가 스크롤 되더라도 메시지의 위치는 창 기준으로 적용되어 동일한 위치에 머무르기 때문이다. 스크롤을 하더라도 계속 요소 밑에 메시지가 위치할 수 있게끔 하려면 position: absolute
를 활용할 수 있다.
문서 기준 좌표는 창이 아닌 문서 왼쪽 위 모서리부터 시작한다. CSS와 비교하면 창 기준 좌표는 position: fixed
에 해당하고 문서 기준 좌표는 맨 위 기준 position: absolute
와 비슷하다고 볼 수 있다.
따라서 문서 내 특정 좌표에 무언가를 위치시키고자 할 땐 position: absolute
와 top, left
등의 속성을 이용해 스크롤 이동에 상관없이 한 좌표에 머물게 할 수 있다. 그러려면 먼저 정확한 좌표를 얻어야 한다.
그런데 요소의 문서 기준 좌표를 제공하는 표준 메서드가 아직 없다. 하지만 두 좌표 체계를 통해 쉽게 관련 수식을 구해줄 수 있다.
pageY
= clientY
+ 문서에서 세로 방향 스크롤에 의해 밀려난 부분의 높이 pageX
= clinetX
+ 문서에서 가로 방향 스크롤에 의해 밀려난 부분의 너비따라서 다음의 함수 getCoords(elem)
은 elem.getBoundingClientRect()
를 사용해 창 기준 좌표를 얻어와 여기에 스크롤에 의해 가려진 영역의 너비 및 높이를 더해준다.
// 문서 기준 좌표 반환
function getCoords(elem) {
let box = elem.getBoundingClientRect();
return {
top: box.top + window.pageYOffset,
right: box.right + window.pageXOffset,
bottom: box.bottom + window.pageYOffset,
left: box.left + window.pageXOffset
};
}
getCoords(elem)
함수를 통해 문서 기준 좌표를 구하고 이를 통해 해당 메시지를 문서 기준으로 고정시키도록 위에서 구현한 createMessageUnder
함수를 다음과 같이 수정해주자.
function createMessageUnder(elem, html) {
let message = document.createElement('div');
message.style.cssText = "position:absolute; color: red";
let coords = getCoords(elem);
message.style.left = coords.left + "px";
message.style.top = coords.bottom + "px";
message.innerHTML = html;
return message;
}
이는 좌표 체계 기준으로만 배치를 해결하려는 시도에서의 접근 방안이다. 단순히 요소 노드를 하나 생성하여 HTML 문서 내 하단 태그로 배치시킨다면 간단하게 해결할 수도 있다.