Skip to content

07. Clipboard·DragDrop·MutationObserver

이 장의 API들은 "브라우저가 조금 더 운영체제처럼 보이게" 만드는 도구들이다. 강력하지만, 그만큼 보안 조건과 사용 맥락을 더 엄격하게 따져야 한다.

학습 목표

  1. Clipboard API의 보안 조건과 사용 시점을 설명할 수 있다.
  2. Drag and Drop의 이벤트 흐름과 현실적인 사용 범위를 이해한다.
  3. MutationObserver의 기본 설정과 cleanup 중요성을 설명할 수 있다.
  4. 이 세 API를 "가능한 기능"이 아니라 "적합한 기능" 기준으로 선택할 수 있다.

1. Clipboard API는 강력하지만 아무 때나 되지 않는다

현대 브라우저에서 클립보드 접근의 중심은 navigator.clipboard다.

  • writeText()
  • readText()
  • write()
  • read()

하지만 이 API는 일반적인 DOM 속성 접근과 다르다.
MDN 기준으로 아래 조건을 함께 봐야 한다.

  • 보안 컨텍스트(대개 HTTPS) 필요
  • 읽기와 쓰기는 브라우저 권한 정책 영향을 받는다
  • 많은 경우 사용자 활성화(user activation) 와 연결되어야 한다

즉, 버튼 클릭 안에서는 잘 되지만 페이지 로드 직후 자동으로 읽거나 쓰려 하면 막히기 쉽다.


2. writeText()readText()부터 생각하자

대부분의 앱은 텍스트 클립보드만으로 충분하다.

js
await navigator.clipboard.writeText(url)
const text = await navigator.clipboard.readText()

이미지나 여러 MIME 타입이 필요할 때만 write()read()를 고려하면 된다.

이렇게 단계적으로 접근하면:

  • 권한 처리 복잡도가 줄고
  • 브라우저 호환성 판단이 쉬워지고
  • UI 안내도 단순해진다

3. 복사 이벤트 오버라이드는 신중해야 한다

원문처럼 copy, cut, paste 이벤트 기반 조작도 가능하다.
하지만 현재는 아래 관점으로 봐야 한다.

  • 사용자의 기대를 과하게 깨지 않는가
  • 접근성을 해치지 않는가
  • "복사 방지" 같은 안티패턴은 아닌가

예를 들어 사용자가 복사한 내용을 마음대로 바꿔 버리면 UX가 나빠질 수 있다.
복사 보조 기능은 좋지만, 통제 욕심이 앞서면 오히려 역효과다.


4. Drag and Drop은 어디에 잘 맞을까?

네이티브 Drag and Drop의 핵심은 DataTransfer다.
이벤트 흐름은 보통 아래처럼 읽으면 된다.

  1. dragstart
  2. dragenter
  3. dragover
  4. dragleave
  5. drop
  6. dragend

여기서 중요한 규칙이 하나 있다.

  • drop을 받으려면 보통 dragover에서 preventDefault()가 필요하다

이 조건을 빼먹으면 드롭이 안 되는 것처럼 보인다.


5. 지금 Drag and Drop을 가장 현실적으로 쓰는 곳

잘 맞는 경우

  • 파일 업로드 드롭존
  • 운영체제 파일을 브라우저에 끌어오는 흐름
  • 데스크톱 스타일 도구 UI

덜 맞는 경우

  • 모바일까지 고려한 카드 재정렬
  • 정교한 드래그 애니메이션이 필요한 보드 UI
  • 터치 중심 제품

이런 경우는 Pointer Events 기반 라이브러리가 더 현실적일 때가 많다.
즉, HTML5 Drag and Drop을 만능 드래그 솔루션처럼 받아들이면 곤란하다.


6. DataTransfer는 드래그 중 데이터 통로다

드래그 앤 드롭에서는 단순히 "무엇을 끌고 있는가"를 DOM으로만 알지 않는다.
event.dataTransfer를 통해 문자열, 파일 목록 등 관련 데이터를 전달한다.

실무에서 특히 중요한 것은 파일 드롭이다.

  • dataTransfer.files로 파일 목록 접근
  • 업로드 전 파일 타입, 크기 점검
  • drag 상태 시각화와 drop 후 정리

7. MutationObserver는 DOM 변경을 비동기로 감시한다

js
const observer = new MutationObserver((records) => {
  console.log(records)
})

observer.observe(target, {
  childList: true,
  subtree: true,
})

옵션은 아래 정도가 핵심이다.

  • childList
  • attributes
  • characterData
  • subtree
  • attributeFilter

원문은 각 옵션을 자세히 소개하는데, 현재는 무엇을 얼마나 좁게 볼 것인가가 더 중요하다.


8. MutationObserver를 과하게 넓히면 바로 무거워진다

문서 전체를 깊게 감시하는 코드는 쉽게 비싸진다.

  • document.body 전체 관찰
  • subtree: true 남발
  • 속성 변경까지 전부 추적

이 패턴은 디버깅에는 편해 보여도 실제 앱에서는 과할 수 있다.
가급적 다음처럼 좁혀야 한다.

  • 필요한 컨테이너만 관찰
  • 필요한 타입만 선택
  • 필요한 속성만 attributeFilter로 지정

9. cleanup 없이 Observer를 두면 결국 문제다

MutationObserver는 이벤트 리스너처럼 생명주기 관리가 필요하다.

  • 화면을 떠났는데도 관찰 지속
  • 같은 컴포넌트가 다시 마운트될 때 중복 관찰
  • 예상보다 많은 콜백 실행

그래서 다음을 기본으로 생각해야 한다.

  • 해제 시 disconnect()
  • 필요하면 takeRecords()로 누락 레코드 회수

이 점은 원문보다 더 강하게 강조해도 좋다.


10. 무엇을 써야 할지 빠르게 판단하는 기준

상황먼저 볼 API
버튼 클릭으로 링크 복사navigator.clipboard.writeText()
운영체제 파일을 드롭해서 업로드Drag and Drop + DataTransfer.files
내부 카드 재정렬Pointer Events 기반 구현 우선 검토
특정 영역 DOM 삽입/삭제 추적MutationObserver

선택 기준은 늘 같다.
브라우저 기본 기능이 잘 맞는가, 아니면 더 적합한 다른 수단이 있는가.


11. 흔한 안티패턴

안티패턴문제점더 나은 방식
페이지 로드 직후 자동 클립보드 읽기 시도보안 정책과 충돌사용자 동작 안에서 수행
Drag and Drop으로 모든 드래그 UX 해결 시도모바일/터치 한계상황에 따라 Pointer 기반 구현 검토
문서 전체 MutationObserver 남발비용 증가, 디버깅 어려움범위와 옵션 최소화
cleanup 없는 observer중복 감시, 메모리 누수disconnect() 기본화

12. PR 리뷰 체크리스트

  • Clipboard 기능이 보안 컨텍스트와 사용자 활성화 흐름 안에서 실행되는가
  • Drag and Drop이 정말 이 문제에 적합한 선택인가
  • 드롭 대상에서 필요한 preventDefault() 처리가 빠지지 않았는가
  • MutationObserver 범위와 옵션이 최소화되어 있는가
  • cleanup 시점에 disconnect()가 보장되는가

핵심 정리

  • Clipboard API는 강력하지만 보안 조건이 붙는다
  • Drag and Drop은 특히 파일 드롭에서 강하고, 모든 드래그 UI의 정답은 아니다
  • MutationObserver는 유용하지만 감시 범위와 cleanup 설계가 품질을 좌우한다