본문 바로가기
개발개발/LifeGraph_인생그래프

[인생 그래프] 클릭 이벤트 핸들러 뜯어보기

by yelimu 2025. 2. 11.

인생그래프 프로젝트 중 유저 클릭 정보를 받는 클릭 이벤트 핸들러이다. 

  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 내부에 그려진다.

이미지를 클릭하면 사이트로 이동합니다.