테마
07. Clipboard·DragDrop·MutationObserver
이 장의 API들은 "브라우저가 조금 더 운영체제처럼 보이게" 만드는 도구들이다. 강력하지만, 그만큼 보안 조건과 사용 맥락을 더 엄격하게 따져야 한다.
학습 목표
- Clipboard API의 보안 조건과 사용 시점을 설명할 수 있다.
- Drag and Drop의 이벤트 흐름과 현실적인 사용 범위를 이해한다.
MutationObserver의 기본 설정과 cleanup 중요성을 설명할 수 있다.- 이 세 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다.
이벤트 흐름은 보통 아래처럼 읽으면 된다.
dragstartdragenterdragoverdragleavedropdragend
여기서 중요한 규칙이 하나 있다.
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,
})옵션은 아래 정도가 핵심이다.
childListattributescharacterDatasubtreeattributeFilter
원문은 각 옵션을 자세히 소개하는데, 현재는 무엇을 얼마나 좁게 볼 것인가가 더 중요하다.
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 설계가 품질을 좌우한다