프로젝트를 진행하면서 JavaScript로 특정 DOM 요소의 위치 정보를 참조하여 조작할 일은 빈번하다. 필자 역시 지금껏 진행했던 매 프로젝트마다 한 번씩은 꼭 마주쳤던 기억이 나는데, 마주칠 때마다 매번 새로워서 구글링하는 스스로에 지치기도 했고 생각보다 이름이 유사하여 혼란스러운 것들이 많아서 따로 한 번 정리해보면 좋겠다는 생각이 들었다. 그래서 이번 글에서는 JavaScript로 참조할 수 있는 DOM 요소의 위치 정보를 정리해보고자 한다.
본격적인 글에 앞서 특정 DOM 요소의 위치 정보를 가져오는 방법을 크게 세 가지로 구분하면 다음과 같다.
- DOM 요소가 자체적으로 가지는 위치 정보
- DOM 요소에
getBoundingClientRect
메서드를 호출하여 참조하는 위치 정보- DOM 요소에 마우스 이벤트가 발생한 경우 마우스 이벤트 객체 안의 위치 정보
그렇다면 이러한 방법으로 참조할 수 있는 위치 정보에는 어떤 것들이 있을까? 지금부터 자세히 살펴보자.
HTMLElement
객체offsetWidth
, offsetHeight
, offsetLeft
, offsetTop
먼저 1번, DOM 요소가 자체적으로 가지는 위치 정보를 살펴보겠다. DOM 요소가 자체적으로 가지는 위치 정보는 DOM API의 HTMLElement
객체가 포함하는 프로퍼티로써 구성되어 있다. HTMLElement
관련 명세는 하단의 MDN 문서를 참조하면 자세하게 살펴볼 수 있다.
📝
HTMLElement
란?: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
HTMLElement
객체 안의 다양한 프로퍼티들 중에서 위치 정보와 관련 있는 offsetWidth
, offsetHeight
, offsetLeft
, offsetTop
에 주목해보고자 한다. 각각의 프로퍼티를 자세히 살펴보기 전에 이름에 공통적으로 붙어 있는 "offset" 접두사를 잠깐 알아보자. CS에서 offset은 배열 등의 자료 구조에서 사용되는 개념인데, 동일 오브젝트 안에서 오브젝트 처음부터 주어진 요소나 지점까지의 변위차를 나타내는 정수형을 의미한다. 쉽게 말해 특정 요소를 기준으로 하는 상대적인 변위차를 의미하는 것이다. 이를 DOM 요소에 적용해보면 요소 자기 자신이 가지는, 혹은 자기 자신을 기준으로 하는 상대적인 위치 정보라고 해석할 수 있겠다. 용어만 보았을 때는 알 듯 말 듯한 느낌이 들 수도 있을 것 같다. 그래서 준비한 하단의 이미지와 함께 살펴보자.
상단 이미지에서 볼 수 있듯이 offsetWidth
와 offsetHeight
는 요소 자체 너비, 높이의 픽셀 값을 의미한다. 다만 한 가지 주의할 점이 있다면, 요소의 margin
값은 너비와 높이에 포함되지 않는다. 즉 요소 자체가 가진 콘텐츠의 너비 높이에 padding
, border
까지 더한 값이 offsetWidth
, offsetHeight
가 된다.
다음으로 얼마 전 프로젝트에서 굉장히 유용하게 다루었던 offsetLeft
와 offsetTop
을 살펴보자. 말 그대로 요소 좌측 상단 모서리를 기준으로 left
, top
픽셀 값을 의미한다. 하지만 특징적인 점 한 가지가 있다. 바로 브라우저 창이나 문서 전체로부터의 left
, top
값이 아니라 참조하는 해당 요소에서 가장 가까운 부모 요소의 좌측 상단 모서리로부터의 left
, top
값이라는 것이다. 상단 이미지처럼 말이다. 그리고 offsetLeft
, offsetTop
는 해당 요소의 margin
값까지 포함한 크기를 기준으로 한다는 점 역시 특징적이다. 그렇다면 offsetLeft
와 offsetTop
은 어떻게 부모 요소를 기준으로 하는 위치 정보를 저장하고 있는 것일까? 그 해답은 바로 HTMLElement
객체가 가지고 있는 offsetParent
프로퍼티에 있다. offsetParent
프로퍼티는 이름 그대로 요소를 기준으로 가장 가까운 부모 요소가 저장되어 있다. 즉 offsetLeft
와 offsetTop
값은 offsetParent
프로퍼티를 토대로 계산되는 것이다.
그런데 offsetParent
에 가장 가까운 부모 요소가 저장된다는 내용은 사실 반은 맞고 반은 틀리다. offsetLeft
, offsetTop
값을 활용할 때 가장 주의해야 하는 함정이 한 가지 있다. 바로 offsetParent
에는 position
값이 지정되어 있는 가장 가까운 부모 요소가 저장된다는 점이다. 즉 offsetParent
의 값은 DOM 트리를 따라 거슬러 올라가면서 가장 먼저 만나는, position
값이 static
이 아닌 부모 요소인 것이다. 그렇다면 만약 기준이 되는 요소로부터 루트 요소인 body
까지 탐색했는데도 position
값이 static
이 아닌 부모 요소가 없다면 offsetParent
의 값은 무엇이 될까? 바로 루트 요소인 body
가 된다. 하단 예제를 통해 이 함정을 실제로 확인해보자.
예제를 보면 동일한 위치 정보의 자식 요소를 가지는 부모 요소 두 개가 있다. 하지만 위의 보라색 예제는 부모 요소의 position
값을 relative
로 지정해준 반면, 아래의 분홍색 예제는 부모 요소의 position
값을 따로 지정해주지 않았다. 그 결과 offsetParent
의 nodeName
이 각각 DIV
, BODY
로 다르게 저장된 것을 확인할 수 있다. 또한 각 자식 요소의 내부 콘텐츠로 렌더링되는 offsetLeft
, offsetTop
값 역시 다르게 나타난다. 보라색 예제의 경우 position
이 relative
인 가장 가까운 부모 요소 <div>
의 좌측 상단을 기준으로 위치 정보가 저장된다. 하지만 분홍색 예제는 부모 요소 중에 position
이 지정된 요소가 없기 때문에 최상단의 루트 요소인 <body>
의 좌측 상단을 기준으로 위치 정보가 저장된다. 이처럼 offsetLeft
와 offsetTop
의 값은 부모 요소에 지정한 position
값에 영향을 받기 때문에 이를 유념하며 사용할 필요가 있다.
지금까지 살펴본 DOM 요소가 자체적으로 가지는 위치 정보를 요약하면 다음과 같다.
💡 DOM 요소가 자체적으로 가지는 위치 정보
offsetWidth
:margin
을 제외한 요소 자체의 너비
: pixel 값,number
타입
offsetHeight
:margin
을 제외한 요소 자체의 높이
: pixel 값,number
타입
offsetLeft
:position
값이static
이 아닌 가장 가까운 부모 요소의 좌측 상단으로부터margin
을 포함한 요소의 좌측 상단까지의 x축 거리
: 만약position
값이 지정된 부모 요소가 없다면<body>
의 좌측 상단이 시작점
: pixel 값,number
타입
offsetTop
:position
값이static
이 아닌 가장 가까운 부모 요소의 좌측 상단으로부터margin
을 포함한 요소의 좌측 상단까지의 y축 거리
: 만약position
값이 지정된 부모 요소가 없다면<body>
의 좌측 상단이 시작점
: pixel 값,number
타입
getBoundingClientRect
메서드x
, y
, left
, top
, right
, bottom
, width
, height
다음으로는 2번, DOM 요소에 getBoundingClientRect
메서드를 호출하여 참조하는 위치 정보를 살펴보자. 본래 getBoundingClientRect
는 Element
객체의 프로토타입 메서드로 존재한다. 그런데 DOM 요소, 즉 HTMLElement
에서 getBoundingClientRect
메서드를 호출할 수 있는 이유는 HTMLElement
가 Element
에게 상속 받는 관계이기 때문이다. 즉 프로토타입 체인 상에서 HTMLElement
객체는 Element
객체의 하위에 존재하기 때문에 getBoundingClientRect
메서드를 상속 받아서 사용할 수 있다.
getBoundingClientRect
메서드를 호출하면 DOMRect
라는 객체를 반환한다. 이 DOMRect
라는 객체는 메서드를 호출한 HTMLElement
, 즉 DOM 요소의 위치 정보를 가지는 객체다. DOMRect
객체는 x
, y
, left
, top
, right
, bottom
, width
, height
를 프로퍼티로 가진다. 이를 이미지와 함께 이해해보면 다음과 같다.
사실 width
와 height
는 CSS로 지정하는 width
, height
와 크게 다를 바가 없다. margin
을 제외하고 요소의 콘텐츠, padding
, border
를 포함한 요소의 너비와 높이를 값으로 가지게 된다. 문제는 바로 width
, height
를 제외한 나머지 프로퍼티들이다. 예상이 될 수도 있겠지만 앞서 살펴본 offsetLeft
, offsetTop
와 마찬가지로 기준점이 중요하다. 과연 x
, y
, left
, top
, right
, bottom
값의 기준점은 어디일까? 상단 이미지에서 확인할 수 있듯이 바로 뷰포트, 즉 브라우저 창의 좌측 상단을 기준으로 한다. 이러한 위치 정보들은 브라우저 창의 좌측 상단을 기준으로 하기 때문에 사용자의 스크롤 위치에 영향을 받을 수밖에 없다. 예를 들어 스크롤을 아래로 내릴수록 브라우저 창의 좌측 상단과 요소가 서로 가까워지므로 y
, top
, bottom
값이 감소할 것이다. 이는 하단 예제를 통해 확인해볼 수 있다.
예제를 보면 getBoundingClientRect
메서드의 반환 값을 콘텐츠로 가지는 사각형의 요소들이 세로로 나열되어 있다. 스크롤을 실제로 내릴 때마다 사각형 내부의 y
, top
, bottom
값이 실시간으로 증가하는 것을 확인할 수 있다. 반대로 스크롤을 올리는 경우 브라우저 창으로부터 요소가 멀어지므로 y
, top
, bottom
값은 당연히 증가하게 된다.
이외에 크게 특징적인 부분은 없지만, 한 가지 주의하여 사용할 내용이 있다면 바로 right
와 bottom
값이다. 익히 알고 있는 CSS의 right
, bottom
계산 방식과는 차이가 있기 때문이다. 이해를 돕기 위해 첨부한 하단 이미지를 확인해보자.
우리가 익히 알고 있는 CSS의 right
, bottom
계산 방식은 상단 이미지의 오른쪽과 같다. 즉 요소와 position
을 적용한 부모 요소의 우측 하단을 기준으로 right
, bottom
값을 계산한다. 그러나 getBoundingClientRect
메서드의 right
, bottom
값은 left
, top
값과 마찬가지로 브라우저의 좌측 상단을 기준으로 계산되기 때문에 CSS에서의 right
, bottom
값과 동일한 값을 기대하는 경우 예상치 못한 결과를 얻을 수 있다. 만약 getBoundingClientRect
메서드를 활용하여 익숙한 CSS의 계산 방식대로 right
, bottom
값을 얻으려면 한 번 가공이 필요하다. right
의 경우 브라우저 창의 너비 값에서 right
값을 빼고, bottom
의 경우 브라우저 창의 높이 값에서 bottom
값을 빼는 방식으로 얻어볼 수 있겠다. 여기서 브라우저 창의 너비와 높이는 window.innerWidth
, window.innerHeight
로 참조할 수 있다. 계산 과정을 보기 쉽게 식으로 정리하면 다음과 같다.
💡
getBoundingClientRect
메서드로 CSS처럼right
,bottom
구하기
right
:window.innerWidth
-getBoundingClientRect
의right
bottom
:window.innerHeight
-getBoundingClientRect
의bottom
그런데 getBoundingClientRect
메서드를 활용하다 보면 한 가지 의문이 든다. x
와 left
, y
와 top
은 완전히 동일한 값을 반환하는데 굳이 왜 구분해놓은 것일까? MDN 문서에도 구체적으로 명시된 바는 없지만 추측하건대 레거시 코드의 흔적이 아닐까 싶다. 실제로 MDN 한국어 문서에서 몇몇 최신 브라우저에서는 getBoundingClientRect
의 반환 값에 x
, y
가 포함되어 있지 않기 때문에 호환성을 고려하여 left
, top
을 사용하라는 내용을 발견할 수 있었다.
지금까지 살펴본 DOM 요소에 getBoundingClientRect
메서드를 호출하여 참조하는 위치 정보를 요약하면 다음과 같다.
💡 DOM 요소에
getBoundingClientRect
메서드를 호출하여 참조하는 위치 정보
width
:margin
을 제외한 요소 자체의 너비
: pixel 값,number
타입
height
:margin
을 제외한 요소 자체의 높이
: pixel 값,number
타입
x / left
: 브라우저 창의 좌측 상단으로부터margin
을 제외한 요소의 좌측 상단까지의 x축 거리
: pixel 값,number
타입
y / top
: 브라우저 창의 좌측 상단으로부터margin
을 제외한 요소의 좌측 상단까지의 y축 거리
: pixel 값,number
타입
right
: 브라우저 창의 좌측 상단으로부터margin
을 제외한 요소의 우측 하단까지의 x축 거리
: CSS의right
처럼 구하고 싶다면window.innerWidth
-right
: pixel 값,number
타입
bottom
: 브라우저 창의 좌측 상단으로부터margin
을 제외한 요소의 좌측 상단까지의 y축 거리
: CSS의bottom
처럼 구하고 싶다면window.innerHeight
-bottom
: pixel 값,number
타입
clientX
, clientY
, offsetX
, offsetY
, pageX
, pageY
, screenX
, screenY
이제 마지막 3번, DOM 요소에 마우스 이벤트가 발생한 경우 마우스 이벤트 객체 안의 위치 정보를 살펴볼 차례다. 이 경우는 사실 엄밀히 말하면 DOM 요소 자체의 위치 정보보다는 사용자의 마우스 포인터와 DOM 요소 사이의 상대적인 위치 정보라고 할 수 있다. 즉 DOM 요소보다는 사용자의 마우스 포인터에 초점이 맞춰져 있다. 그럼에도 이번 글에서 이를 다루는 이유는 후술하겠지만 앞서 살펴본 것과 유사하게 "offset" 접두사가 붙은 프로퍼티들이 존재하기 때문에 혼동의 여지가 있기도 하고, 사용자의 마우스 포인터와 DOM 요소를 기준으로 하는 상대적인 위치 정보를 활용할 일이 꽤 많기 때문이다.
서두가 길었으니 본론으로 바로 들어가면, 마우스 이벤트 객체 안의 다양한 프로퍼티들 중에 이번 글에서는 clientX
, clientY
, offsetX
, offsetY
, pageX
, pageY
, screenX
, screenY
를 다뤄보고자 한다. 이러한 프로퍼티들이 들어 있는 이벤트 객체는 이벤트 핸들러에 전달하는 콜백 함수 내부에서 참조할 수 있다. 암묵적으로 이벤트 핸들러에 전달하는 콜백 함수의 첫 번째 매개변수로는 이벤트 객체가 전달되는데, 마우스 이벤트의 경우 이 이벤트 객체 안에 마우스 포인터 위치와 관련된 다양한 정보를 포함한다. 아마 JavaScript로 클릭 이벤트를 처리해본 적이 있다면 자주 봤을 것이다.
살펴봐야 할 프로퍼티들이 많아서 복잡할 것 같지만 꽤나 직관적으로 명명되어 있기 때문에 이름과 함께 이해하면 생각보다 쉽게 받아들일 수 있다. 우선 하단의 이미지를 먼저 살펴보자.
웬만하면 하나의 이미지로 설명하는 게 좋겠지만 너무 가독성이 떨어지는 관계로 이미지를 두 개로 나누어 제작해보았다. 먼저 상단 이미지의 screenX
, screenY
, pageX
, pageY
를 살펴보자. 마우스 이벤트 객체 안에 포함된 위치 정보이기 때문에 당연히 기준점은 브라우저가 마우스 이벤트를 감지한 그 순간 사용자의 마우스 포인터 위치가 될 것이다. 이제 그 반대측의 기준점이 어디인지만 파악하면 될 일이다.
먼저 screenX
와 screenY
의 경우 이름에서 유추할 수 있듯이 스크린, 즉 사용자의 모니터 좌측 상단을 기준으로 한다. 즉 screenX
와 screenY
는 모니터 좌측 상단을 기준으로 사용자의 마우스 포인터까지의 x축, y축 거리를 계산한 값이다.
pageX
와 pageY
의 경우 역시 마찬가지로 이름에서 유추할 수 있듯이 한 페이지, 즉 HTML 문서 전체의 좌측 상단을 기준으로 마우스 포인터까지의 x축, y축 거리를 계산한 값이다. 여기서 HTML 문서 전체란 말 그대로 브라우저 창에 보이는 일부분이 아닌 스크롤이 가능한 전체 영역을 의미한다. 그러므로 pageX
와 pageY
는 스크롤 위치에 영향을 받는 가변적인 값을 반환하게 된다. 예를 들어 스크롤을 많이 내릴수록 HTML 문서 좌측 상단과는 멀어지기 때문에 그만큼 스크롤을 내리기 전보다 증가된 pageY
값을 반환할 것이다. 스크롤 위치와 관련된 내용을 언급하는 이유는 바로 다음에 살펴볼 clientX
, clientY
와의 차이점 때문이다. 하단의 이미지를 먼저 살펴보자.
상단 이미지에서 볼 수 있듯이 clientX
와 clientY
는 앞서 살펴본 pageX
, pageY
와 달리 브라우저 창의 좌측 상단을 기준으로 마우스 포인터까지의 x축, y축 거리를 계산한 값이다. 그러므로 스크롤 위치와는 관계없이 고정되어 있는 브라우저 창을 기준으로 항상 동일한 값을 반환한다.
마지막으로 offsetX
와 offsetY
는 이벤트가 발생한 타깃 요소의 좌측 상단을 기준으로 마우스 포인터까지의 x축, y축 거리를 계산한 값이다. 앞서 1번 항목에서 살펴봤던 "offset"의 의미를 잠깐 되짚어보면, offsetX
와 offsetY
역시 이벤트가 발생한 요소 자기 자신을 기준으로 하는 상대적인 위치 정보이기 때문에 "offset"이라는 접두사를 붙여 명명했음을 짐작할 수 있다. 꽤나 일관적인 네이밍 컨벤션이 아닐 수 없다!
상단 예제를 통해 마우스 이벤트 객체 내부의 위치 정보를 확인해볼 수 있다. 예제의 흰 배경 위에서 마우스 포인터를 움직여보면 마우스 포인터를 추적하는 컴포넌트가 렌더링될 것이다. 이 컴포넌트의 내부 콘텐츠로 마우스를 이동할 때마다 실시간으로 변하는 위치 정보 값을 확인할 수 있도록 구성해놓았다.
한 가지 주의할 점이 있다면 순수 JavaScript 환경에서는 마우스 이벤트 객체를 통해 정상적으로 모든 프로퍼티를 참조할 수 있지만, React 환경에서는 좀 다르다는 것이다. React 환경에서의 마우스 이벤트는 얼핏 보면 DOM API의 마우스 이벤트와 동일한 것 같지만 React에서 자체적으로 구성한 합성 이벤트이기 때문이다. 그러므로 React 환경의 마우스 이벤트 객체에서 clientX
, clientY
, pageX
, pageY
, screenX
, screenY
는 정상적으로 참조가 가능하지만 offsetX
, offsetY
를 참조하면 다음과 같이 undefined
가 반환된다.
// 마우스 이벤트 핸들러의 콜백 함수
const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {
console.log(event.offsetX, event.offsetY); // undefined undefined
};
그렇다면 React 환경에서 offsetX
, offsetY
를 참조할 수 있는 방법은 없는 것일까? 그건 아니다. React 환경의 마우스 이벤트 객체에 있는 nativeEvent
프로퍼티를 활용하면 된다. nativeEvent
프로퍼티는 말 그대로 순수 JavaScript 환경의 마우스 이벤트 객체를 저장하고 있다. 실제로 console.log
메서드를 호출하여 확인해보면 다음과 같이 객체 이름부터 다른 것을 알 수 있다.
상단 이미지의 위쪽부터 React 환경에서의 nativeEvent
프로퍼티, 마우스 이벤트 객체 자체를 console.log
로 확인해본 결과다. 이름만 봐도 합성 이벤트인지 아닌지 명시적으로 파악할 수 있다. 그렇다면 React는 왜 DOM API의 이벤트를 그대로 사용하지 않고 합성 이벤트를 사용하는 것일까? 공식 문서에는 구체적인 이유가 명시되어 있지 않아 리서치를 해본 결과, React 환경에서 DOM API의 이벤트 객체를 래핑하여 합성 이벤트 객체로 사용하는 이유는 크로스 브라우징을 쉽게 구현하기 위함이다. 브라우저마다 이벤트 객체의 명세에 조금씩 차이가 있는데, React는 이 차이를 하나의 합성 이벤트로 래핑함으로써 모든 브라우저에서 이벤트가 동일하게 동작하도록 보장하는 것이다. 즉 다양한 환경에서 일관된 이벤트 처리를 위해 합성 이벤트로 래핑하는 것이라고 볼 수 있다. 참고로 React 17 버전 이전에는 다양한 이벤트 간에 이벤트 객체를 재사용하는 이벤트 풀링 방식을 구현하기 위한 목적도 있었지만, React 17 버전 이후에 이벤트 풀링은 명세에서 삭제되어 더 이상 사용되지 않는다. 자세한 내용은 하단의 공식 문서를 참조하면 확인할 수 있다.
📝 React 17 버전 이후 삭제된 이벤트 풀링
: https://legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html#no-event-pooling
그러나 React 공식 문서에서도 웬만하면 nativeEvent
프로퍼티의 참조를 권장하지 않기도 하고, 리서치해본 결과 nativeEvent
객체의 offsetX
와 offsetY
를 활용하면 컴포넌트 렌더링이 정상적으로 동작하지 않는 사례가 많은 것으로 보아 offsetX
와 offsetY
는 되도록 사용하지 않는 편이 바람직할 것 같다. 예상하건대 아무래도 nativeEvent
를 참조하면 직접 DOM을 참조하게 되므로 virtual DOM을 생성하여 실제 DOM과 비교하는 과정을 거치는 React 환경에서 내부적으로 문제가 발생하거나, 최적화를 해주지 못하는 듯하다. 그러므로 offsetX
와 offsetY
를 사용할 일이 있다면 앞서 살펴본 다른 위치 정보를 사용하여 우회하는 방식으로 구현해볼 수 있겠다. 예를 들자면 하단 이미지와 같은 방식으로 말이다.
지금까지 살펴본 DOM 요소에 마우스 이벤트가 발생한 경우 마우스 이벤트 객체 안의 위치 정보를 요약하면 다음과 같다.
💡 DOM 요소에 마우스 이벤트가 발생한 경우 마우스 이벤트 객체 안의 위치 정보
clientX
: 브라우저 창의 좌측 상단으로부터 사용자의 마우스 포인터까지 x축 거리
: pixel 값,number
타입
clientY
: 브라우저 창의 좌측 상단으로부터 사용자의 마우스 포인터까지 y축 거리
: pixel 값,number
타입
offsetX
: 마우스 이벤트가 감지된 타깃 요소의 좌측 상단으로부터 사용자의 마우스 포인터까지 x축 거리
: pixel 값,number
타입
: 🚨 단, React 환경에서는 오작동 우려가 있으므로 사용을 지양하는 것을 권장 🚨
offsetY
: 마우스 이벤트가 감지된 타깃 요소의 좌측 상단으로부터 사용자의 마우스 포인터까지 y축 거리
: pixel 값,number
타입
: 🚨 단, React 환경에서는 오작동 우려가 있으므로 사용을 지양하는 것을 권장 🚨
pageX
: HTML 문서 전체의 좌측 상단으로부터 사용자의 마우스 포인터까지 x축 거리
: pixel 값,number
타입
pageY
: HTML 문서 전체의 좌측 상단으로부터 사용자의 마우스 포인터까지 y축 거리
: pixel 값,number
타입
screenX
: 모니터 스크린의 좌측 상단으로부터 사용자의 마우스 포인터까지 x축 거리
: pixel 값,number
타입
screenY
: 모니터 스크린의 좌측 상단으로부터 사용자의 마우스 포인터까지 y축 거리
: pixel 값,number
타입
여기까지 총 세 가지 항목으로 구분하여 DOM 요소와 연관되어 참조할 수 있는 위치 정보들을 정리해보았다. 이 글을 작성하게 된 목적이 offsetX
, offsetLeft
등 유사한 이름의 프로퍼티가 많은 나머지 헷갈려서 확실하게 정리하고자 함이었는데, 글을 작성하고 이해를 돕는 이미지도 제작하면서 스스로도 좀 더 확실하게 관련 개념을 정립할 수 있었다. 실제로 마우스를 추적하는 컴포넌트를 제작해야 한다든가, 사용자의 마우스 이벤트에 따라 DOM 요소의 위치를 이동시켜야 한다든가 하는 경우 빈번하게 활용하게 되는 개념들인 만큼 한 번쯤 정리하고 가면 좋은 것 같다. 이 글을 읽으시는 분들께도 많은 도움이 되었으면 하는 바람이다.
🙏 출처
https://developer.mozilla.org/ko/docs/Web/API/HTMLElement
https://developer.mozilla.org/en-US/docs/Web/API/Element
https://developer.mozilla.org/ko/docs/Web/API/Element/getBoundingClientRect
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
https://legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html#no-event-pooling
예제까지해서 정성들여 정리해주신 포스트 덕분에 위치값을 잘 잡았네요! ^^/ 감사합니다!👍