본문 바로가기

Javascript

[js][trouble-shooting] drag and drop 이벤트 구현 시 주의 사항 - drag 이벤트가 drag를 놓은 후에 또 발생함. 근데 clientX, clientY 값은 0임. 왜???

문제

drag 이벤트는 드래그인 중에 계속 발생한다.

근데, 특정 조건에서는 drag를 놓을 때 한번 더 발생한다.

문제는 이 때 clientX 같은 일부 값이 제대로 안들어있고 0으로 나와서 drag 이벤트 핸들러에 clienX 관련 로직이 들어있으면 에러가 나버린다.

 

코드

import React from "react";

export default function DADMoveTest() {
  return (
    <div
      style={{ width: "500px", height: "500px", backgroundColor: "aliceblue" }}
    >
      <div
        draggable={true}
        onDragStart={() => {
          console.log("onDragStart");
        }}
        // 드래그를 놓을 때 한번 더 실행됨. clientX는 0임
        onDrag={(ev) => {
          console.log("onDrag", ev.clientX);
        }}
      >
        hello{" "}
      </div>
    </div>
  );
}

 

원인

위에는 리엑트 코드이지만, 바닐라 js에서도 동일한 문제가 생긴다.

실험 해보니, drag를 놓는 장소(즉, drop 이벤트 발생 위치)에 dragOver 이벤트가 존재하고, event.preventDefault()를 해주면 문제가 생기지 않았다.

 

해결 코드 예시

import React from "react";

export default function DADMoveTest() {
  return (
    <div
      style={{ width: "500px", height: "500px", backgroundColor: "aliceblue" }}
      // 이거 있어야 함
      onDragOver={(ev) => {
        console.log("onDragOver");
        // 이거 있어야 함
        ev.preventDefault();
      }}
    >
      <div
        draggable={true}
        onDragStart={() => {
          console.log("onDragStart");
        }}
        // 이제 드래그 놓을 때 실행 안됨
        onDrag={(ev) => {
          console.log("onDrag", ev.clientX);
        }}
      >
        hello{" "}
      </div>
    </div>
  );
}

 

원인의 원인

왜 이런 문제가 생길까?

일단 mdn이나 stackoverflow를 찾아봐도 유사한 사례를 찾지 못했다.

추측인데, 원래 drag 이벤트는 dragOver와 ev.preventDefault를 정의해야 drop 이벤트가 호출된다.

아마도 이벤트의 순차적 트리거에 뭔가가 있는 것 같은데, 이것도 그런 문제가 아닐까 싶다.

 

그리고 onDragover는 event.target일 필요는 없고 그냥 최상단에 있어도 된다.

즉, document에다가 걸어도 된다.

버블링쪽 문제인가...?