이번에 초대권 이벤트가 있어 초대코드를 복사하는 기능을 구현하고 그 페이지를 주로 카카오톡을 통해 공유하는 기획이 있었다.
그런데 안드로이드폰 카카오톡 브라우저에서만 복사하기가 실패하는 것이다. (ios는 되고, aos도 네이버브라우저도 되는데 ㅠ ... 카톡 브라우저가 좀 까다로운 것 같다.)
기존 구현 방법
: execCommand('copy') -> deprecated*
: navigator.clipboard.writeText
-> 주로 사용하는 방법이나, 안드로이드 카카오 인앱에서 지원되지 않는 문제 발견
해결책
: window.clipboardData.setData(format, data)
ClipboardEvent.clipboardData 속성은 사용할 수 있는 DataTransfer 객체를 보유. 복붙 기능은 이 clipboardData의 setData를 통해 복사할 데이터를 지정하고, 붙여넣기를 할때에는 getData로 가져온다.
const source = document.querySelector("div.source");
source.addEventListener("copy", (event) => {
const selection = document.getSelection();
event.clipboardData.setData("text/plain", selection.toString().toUpperCase());
event.preventDefault();
});
getSelection은 사용자가 선택한 범위에 대해 selection객체를 가져오는데 이를 toString()하면 문자로 반환한다. 그 데이터를 setData 시켜 복사할 데이터를 준비하는 것이다.
OS 및 브라우저별 꼼꼼한 처리가 필요했기 때문에, 위의 방법으로 구현하면서 실패 시 예외상황에 대한 처리를 진행한 copy 라이브러리를 적용했다. copy-to-clipboard
리액트로 프로젝트를 진행하고 있기에 react-copy-to-clipboard를 사용했다. 이 라이브러리의 좋은 점은 onCopy라는 프롭의 기능이었다. 이 프롭함수의 파라미터로 복사결과를 boolean값으로 주기 때문에 조건에 따라 후 기능을 추가할 수 있다.
이번 기획에서는 복사를 하고 '복사를 완료했어요.'라는 토스트 메시지를 줄 수 있는 기능을 추가했다. 또한 복사할 text도 전달받을 수 있기 때문에 더 많은 기능을 구현할 수 있을 것 같다.
*참고자료
https://web.dev/async-clipboard/ -> good
https://developer.mozilla.org/en-US/docs/Web/API/Element/copy_event
도움이 되었습니다 감사합니다!