인생그래프 프로젝트 중 유저 클릭 정보를 받는 클릭 이벤트 핸들러이다.
const handleClick = (e: MouseEvent<HTMLDivElement>) => {
const rect = e.currentTarget.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
addPoint({ id: Date.now(), x, y, title: "" }); // 클릭한 좌표 추가
};
currentTarget 과 target은 어떻게 다른걸까 궁금해져서 찾아보게 됐다.
https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget
Event: currentTarget property - Web APIs | MDN
The currentTarget read-only property of the Event interface identifies the element to which the event handler has been attached.
developer.mozilla.org
MDN 에서 이 부분에 대해 예제로 설명하고 있다.
<div id="parent">
Click parent
<div id="child">Click child</div>
</div>
<button id="reset">Reset</button>
<pre id="output"></pre>
부모 요소 안에 자식 요소가 위치하고있다.
const output = document.querySelector("#output");
const parent = document.querySelector("#parent");
parent.addEventListener("click", (event) => {
const currentTarget = event.currentTarget.getAttribute("id");
const target = event.target.getAttribute("id");
output.textContent = `Current target: ${currentTarget}\n`;
output.textContent += `Target: ${target}`;
});
클릭했을때 currentTarget과 target 각각의 id를 보여주는 함수를 parent의 이벤트 핸들러로 할당한다.
child 안쪽을 클릭하면
target : child, current target : parent
parent 내부이면서 child 바깥쪽 영역을 클릭하면
target : parent , current target : parent
target은 클릭 이벤트가 발생한 요소, current target은 이벤트 핸들러를 갖고있는 요소를 가리킨다.
이벤트 핸들러 외부에서의 currentTarget.value은 null 을 반환한다.
또한 current target 속성은 read-only이다.
따라서 input 에 입력된 값을 지울때 작성했던 e.target,value = "" 이런 식의 접근이 불가능하다.
...
return (
<div className="graph-container" onClick={handleClick}>
{points.map((point) => (
<Point
key={point.id}
x={point.x}
y={point.y}
title={point.title}
onChange={(e) => handleChange(e, point.id)}
ref={inputRef}
/>
))}
</div>
);
};
그래프 컨테이너 div에 이벤트 핸들러를 할당했으니 currentTarget 가 가리키는 대상이 된다.
코드를 다시 보자
const rect = e.currentTarget.getBoundingClientRect();
getBoundingClientRect() 메서드는 pdding, border를 포함해 전체 엘리먼트가 들어있는 가장 작은 사각형인 DOMRect 객체를 반환한다.
전반적인 사각형의 위치와 크기인, left, top, right, bottom, x, y, width, height 프로퍼티를 갖는다. (픽셀 단위)
https://developer.mozilla.org/ko/docs/Web/API/Element/getBoundingClientRect
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
그러면 이 코드에서 rect.left 와 rect.top 이 가리키는게 뭔지 알게 됐다.
→ div-container 박스가 뷰포트에서 떨어져있는 위치이다.
MouseEvent.e.clientX / e.clientY 는 마우스 이벤트가 갖는 읽기 전용 속성이다.
이벤트가 발생한 어플리케이션 뷰포트 내에 수평 / 수직 좌표를 제공한다.
즉 브라우저 화면(뷰포트)의 절대적인 좌표임.
https://developer.mozilla.org/ko/docs/Web/API/MouseEvent/clientX
Window.screenX / screenY 와 값 차이가 나는걸 볼수있다.
흰색 화면 가장 끝쪽에 마우스를 댔을때 clientX값은 0 (캡쳐엔 2, 1 이지만)
브라우저 위치를 옮기면 screenX 값이 달라진다.
const handleClick = (e: MouseEvent<HTMLDivElement>) => {
const rect = e.currentTarget.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
addPoint({ id: Date.now(), x, y, title: "" }); // 클릭한 좌표 추가
};
그래서 결국 이 코드는
1. 클릭 이벤트가 발생했을때
2. 브라우저 내의 뷰포트 위치에서
3. 이벤트 핸들러가 등록된 요소가 뷰포트로부터 떨어진 위치를 뺀 값을 좌표로 하는
4. point 값이 추가된다
→ 상대적인 x, y 좌표가 반환됨
→ Point 컴포넌트 위치를 이어서 만드는 그래프는 graph-container 내부에 그려진다.
'개발개발 > LifeGraph_인생그래프' 카테고리의 다른 글
[인생 그래프] 이모지 피커를 추가하자 (0) | 2025.02.11 |
---|---|
[인생 그래프] 이미지 저장하기 (html2canvas + file-saver) (0) | 2025.02.11 |
[인생 그래프] 그래프가 이상하다 (0) | 2025.02.10 |
[인생 그래프] 클릭 데이터 전역상태로 관리하기 (0) | 2025.02.10 |
[인생 그래프] 클릭한 위치에 컴포넌트 추가하기 (0) | 2025.02.10 |