브라우저 Clipboard 접근(JS 복사-붙여넣기)

최원빈·2022년 10월 17일
0

시스템 클립보드에 접근해 복사-붙여넣기를 하는 것을 구현하려면 clipboard.js 라이브러리를 사용하면 편할 것이다.

군대가 라이브러리를 사용하지 못하는 환경이라 바닐라로 구현할 일이 생겨서 한 번 정리해 보았다.

클립보드에 특정 값을 복사시키는 법,
클립보드에 복사되어있는 값을 읽는 법 등 다양한 방법으로 알아보자.

1. document.execCommand("copy") 사용하기

셀렉션(클라이언트 입장에서의 드래그된 상태)을 만든 뒤에 document.execCommand("copy")를 호출하면 클립보드에 그대로 복사가 된다.

셀렉션을 조정하는 법은 다양하지만, 전체 복사를 구현할 예정이었으니

<input> 엘리먼트나 <textarea> 엘리먼트의 select() 메소드를 사용하면, 아주 쉽게 전체 선택이 가능하다.

// ex) 입력폼에 단순 복사 기능
document.getElementById("copy-input").select();
document.execCommand("copy");

입력 폼에 있는 값의 복사는 이렇게 쉽게 구현이 가능하다.
이를 활용해서 JavaScript 변수도 복사할 수 있다.

  1. 입력이 가능한 element를 생성한다.
  2. 원하는 변수를 element.value에 담아준다.
  3. select() 후 execCommand("copy")로 복사한다.
  4. 복사를 마쳤으니 처음 만든 element를 제거한다.
// ex) 특정 변수값 복사하기
const someData = "이걸 복사하고 싶어요";

let tempInput = document.createElement("input")
tempInput.value = someData;

// 굳이 body일 필요는 없습니다. 아무 엘리먼트나 지정해서 작성해도 무관합니다.
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand("copy");
document.body.removeChild(tempInput);

콘솔에 복사해서 그대로 찍어보자. 잘 된다.

근데 과정이 효율적이지 못한게 쓰면서도 보인다.
노드를 만들고 select하는 과정이 필수로 들어가야 한다는 점이 누가 봐도 비효율적이다.


MDN 문서에서도 Deprecated되었다고 안내한다.

2. ClipboardEvent.clipboardData 활용하기

ClipboardEvent에서 발생하는 이벤트 인자에는 clipboardData가 들어있다.
ClipboardEvent에는 cut(잘라내기), copy(복사), paste(붙여넣기)가 포함된다.

특정 엘리먼트에 이벤트리스너를 등록해 발생하는 이벤트 인자를 통해 구현이 가능하다.

// ex) 붙여넣는 값을 콘솔에 출력
window.addEventListener("paste", (e) => {
  console.log(e.clipboardData.getData("text"));
})

// ex) 모든 복사에 특정 값 복사시키기
window.addEventListener("copy", (e) => {
  e.preventDefault();
  e.clipboardData.setData("text", "이 값이 복사될걸요?");
})

getData, setData 메소드의 첫 번째 인자로 데이터 타입을 지정해주면 읽고 쓸 수 있다.
문제라면, paste에서 발생하는 이벤트 인자에는 setData가 없다.
=> 복사와 관련 없는 기능에 setData를 통해 clipboard의 데이터를 수정할 수 없는 것.

얘도 뭔가 나사가 하나씩 빠져있다.
게다가 IE에선 window.clipboardData 처럼 전역 객체로 제공한다.
브라우저별로 완전히 구현을 달리해야 하는 것. (사실 브라우저 지원 현황이 개판이라 통일이 당장은 불가능하겠다만은..)

3. ClipboardApi 활용하기


이야.. document.execCommand() 를 대체하기 위해 만들어진 방식이라는 점이 상당히 기대되는 방식이다.

navigator.clipboard.readText().then((clipText) => {
  document.querySelector(".editor").innerText += clipText);
}

콘솔에 바로 활용해보기 위해 editor부분을 body 엘리먼트로 바꿔 찍어보았다.

navigator.clipboard.readText().then((clipText) => {
  document.body.innerText += clipText;
})


???

document가 focus되어야한다고 한다.
아무 엘리먼트의 click이벤트에 리스너를 달아 구현해보니 잘 동작한다.

드디어 copy, paste 등 클립보드 이벤트를 사용하지도 않고,
새로운 엘리먼트를 생성하고 지워내는 과정 없이도 클립보드에 접근하는 방법을 찾았다!

이 방식의 단점이라면

  1. 붙여넣을 때 브라우저가 권한을 묻는다. (최초 1회)
  2. 복사할 때에도 Dom focus에 집착한다.

붙여넣는건 그렇다쳐도 복사할 땐 focus에 왜 집착할까?

오늘은 연등시간이 끝났으니 언젠간 생각나면 알아봐야지

profile
FrontEnd Developer

0개의 댓글