Hell路 World 삐약-
[TIL.22] 주소복사 클립보드 복사 공유하기 window.clipboard 안드로이드 카톡 인앱 브라우저 안될때 예외처리 execCommand 본문
TIL_any

[TIL.22] 주소복사 클립보드 복사 공유하기 window.clipboard 안드로이드 카톡 인앱 브라우저 안될때 예외처리 execCommand

날으는쏘피 2022. 12. 25.
728x90

얼마전에 홈페이지에서 제공하는 서비스에 공유하기 기능을 추가하게 됐는데 간단하다고 생각했던 기능에 의외로 예외가 있어 짧게 정리해보려고 한다. 

 

단순히 주소 복사를하는 기능으로 clipboard를 사용하는데 이게 안먹히는 브라우저가 있던것이다..!

아니 근데 몰랐던것도 당연한게 인앱브라우저까지 어떻게 다 생각해ㅠ

후하.. 그게 카톡이라면 모르면 안되긴하지...ㅠ

 

 

Anyway.

이에 대해서는 하단에서 설명하는 것으로 하고

일단 현재 보고있는 화면의 url을 복사하는 기능은 아래와같이 구현했다. 

 

navigator.clipboard

copyCurrentUrl(){
        const currentUrl = window.location.href;

            navigator.clipboard.writeText(currentUrl).then(res =>{
                alert("주소가 복사되었습니다.\n원하는 곳에 붙여넣기(Crtl+V)해주세요.")
            })
	},

현재 url window.loacation.herf  clipboard에 복사하는 기능으로 2022년 현재 웬만한 브라우저에서는 무리없이 사용할 수 있다. 

 

 

Clipboard API - Web APIs | MDN

The Clipboard API provides the ability to respond to clipboard commands (cut, copy, and paste) as well as to asynchronously read from and write to the system clipboard.

developer.mozilla.org

clipboard 함수는 프로미스를 반환하기 때문에 then으로 성공했을 때, 그리고 catch로 실패했을때의 예외처리를 해주면 되는데 일반전인 테스트 환경에서 진행했을때 에러 없이 기능이 정상적으로 작동했기때문에 에러처리는 따로 하지 않았었다. 

 

 

그런데..! 

 

실제 서비스에 배포하고 난 뒤에 해당 기능을 사용해 카카오톡으로 공유를 하는데....

공유된 url을 클릭해 카톡 인앱 브라우저로 우리 웹사이트에 들어가서 다시 공유하기 버튼을 누르면 기능이 작동하지 않는 것이다...!

 

인앱 브라우저에서 clipboard 기능이 안되는 상황에 대해 검색해보니 다양한 해결책들이 나왔다.

 

모바일의 경우, 아예 인앱브라우저에서의 오픈 기능을 막아버리거나 여러가지 다양한 예외처리가 있었는데...

(navigator.userAgent로 모바일 확인 후 안드로이드면 url앞에 intent를 추가하는 방법)

 

팀장님께서 어플을 컨트롤하는건 좋지 않은 방법같다고 옛날에 썼던 방법이라는 execCommand로 해보라고 알려주셨다. 

 

document.execCommand

 

Document.execCommand() - Web APIs | MDN

When an HTML document has been switched to designMode, its document object exposes an execCommand method to run commands that manipulate the current editable region, such as form inputs or contentEditable elements.

developer.mozilla.org

위 문서를 보면 execCommand는 더이상 권장되지 않는 기능이라고 한다. 

하지만 권장되지 않을뿐 기능은 정상작동하니 쓰지 말라는 말은 아님ㅋㅋㅋㅋㅋ

 

사실 clipboard와 비교하기보다는... 과거(?)에 input 요소의 값(value)을 컨트롤하는데 사용된 함수였던 것 같다. 어떤 인자를 넘기느냐에 따라 폰트 스타일 등 다양한 기능을 사용할 수 있는데 이 글에서 정리할 기능은 'copy'이다.

 

 

※ 주의할점은 이 기능은 input또는 textarea같은 선택(select) 가능한 요소에 쓸 수 있다는 점이고 해당 요소가 hidden 또는 display:none으로 가려진 요소면 안된다는 것이다. 

 

안드로이드Android 카톡 인앱브라우저에서 작동하지 않았던 clipboard기능 예외처리를 추가한 코드는 아래와 같다. 

copyCurrentUrl(){
        const currentUrl = window.location.href;

            navigator.clipboard.writeText(currentUrl).then(res =>{
                alert("주소가 복사되었습니다.\n원하는 곳에 붙여넣기(Crtl+V)해주세요.")
            }).catch((error) =>{
                const element = document.createElement('input');
                element.value = currentUrl;
                element.setAttribute('readonly', '');
                element.style.position = 'absolute';
                element.style.left = '-9999px';
                document.body.appendChild(element);
                element.select();
                document.execCommand('copy');
                alert("주소가 복사되었습니다.\n원하는 곳에 붙여넣기(Crtl+V)해주세요.")
                document.body.removeChild(element);
            })
    },

execCommand는 선택된 요소의 value를 컨트롤하는 함수이니만큼 임의의 input요소를 화면에 보이지 않는 곳에 만들어 url를 value로 설정하고 그 값을 document.execCommand('copy') 복사 한다. 

그리고 해당 요소를 삭제하는 것으로 마무리-!

 

보이지 않는 곳에 input요소를 만들고 써먹느라 뭔가 스타일 코드가 굉장히 길어진 느낌....

 

 

아니 근데 아이폰에서는 다 정상작동하고 네이버도 디바이스 상관없이 정상작동했는데 왜 안드로이드 카톡 인앱브라우저만 안되는거야........?????

후하... 이렇게 또 하나 배워갑니다........

 

 

 

 

참고:

 

[JavaScript] 특정 문자를 클립보드로 복사하기

참고한 문서

noritersand.github.io

 

728x90
Comments