개요
클립 보드에 복사하기위한 세 가지 기본 브라우저 API가 있습니다.
- 비동기 클립 보드 API
[navigator.clipboard.writeText]
- Chrome 66 에서 제공되는 텍스트 중심 부분 (2018 년 3 월)
- 액세스는 비동기식이며 JavaScript Promises를 사용 하므로 보안 사용자 프롬프트 (표시되는 경우)가 페이지의 JavaScript를 방해하지 않도록 작성할 수 있습니다.
- 변수에서 직접 텍스트를 클립 보드로 복사 할 수 있습니다.
- HTTPS를 통해 제공되는 페이지에서만 지원됩니다.
- Chrome 66에서 활성 탭의 페이지는 권한 프롬프트없이 클립 보드에 쓸 수 있습니다.
document.execCommand('copy')
- 대부분의 브라우저는 2015 년 4 월 ~ 현재이를 지원합니다 (아래 브라우저 지원 참조).
- 액세스는 동 기적입니다. 즉, 표시 및 사용자가 보안 프롬프트와 상호 작용하는 것을 포함하여 완료 될 때까지 페이지에서 JavaScript를 중지합니다.
- DOM에서 텍스트를 읽고 클립 보드에 배치합니다.
- ~ 2015 년 4 월 ~ 테스트 동안 클립 보드에 쓰는 동안 Internet Explorer 만 권한 프롬프트를 표시하는 것으로 나타났습니다.
- 복사 이벤트 재정의
- 복사 이벤트 재정의에 대한 클립 보드 API 설명서를 참조하십시오 .
- 복사 이벤트에서 클립 보드에 표시되는 내용을 수정하고 일반 텍스트 이외의 다른 형식의 데이터를 포함 할 수 있습니다.
- 질문에 직접 대답하지 않으므로 여기에서 다루지 않습니다.
일반적인 개발 노트
콘솔에서 코드를 테스트하는 동안 클립 보드 관련 명령이 작동하지 않아도됩니다. 일반적으로 페이지가 활성화되어 있거나 (Async Clipboard API) 클립 보드 document.execCommand('copy')
에 액세스 할 수 있도록 사용자 상호 작용 (예 : 사용자 클릭)이 필요합니다 ( 자세한 내용은 아래 참조).
중요 (여기에서 2020/02/20으로 표시)
이 게시물은 원래 교차 출처 IFRAME 및 기타 IFRAME "샌드 박스" 에서 권한이 더 이상 사용되지 않기 때문에 임베디드 데모 "Run code snippet"버튼 및 "codepen.io example"이 일부 브라우저 (Chrome 및 Microsoft Edge 포함)에서 작동하지 못하게합니다. ).
자체 웹 페이지를 개발하려면 HTTPS 연결을 통해 해당 페이지를 제공하여 테스트 및 개발하십시오.
다음은 코드 작동을 보여주는 테스트 / 데모 페이지입니다.
https://deanmarktaylor.github.io/clipboard-test/
비동기 + 폴백
새로운 Async Clipboard API에 대한 브라우저 지원 수준으로 인해 document.execCommand('copy')
브라우저 범위 를 넓히기 위해 메소드로 대체하려고 할 것 입니다.
다음은 간단한 예입니다 (이 사이트에 포함되지 않은 경우 위의 "중요"참고 사항 참조).
function fallbackCopyTextToClipboard(text) {
var textArea = document.createElement("textarea");
textArea.value = text;
// Avoid scrolling to bottom
textArea.style.top = "0";
textArea.style.left = "0";
textArea.style.position = "fixed";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Fallback: Copying text command was ' + msg);
} catch (err) {
console.error('Fallback: Oops, unable to copy', err);
}
document.body.removeChild(textArea);
}
function copyTextToClipboard(text) {
if (!navigator.clipboard) {
fallbackCopyTextToClipboard(text);
return;
}
navigator.clipboard.writeText(text).then(function() {
console.log('Async: Copying to clipboard was successful!');
}, function(err) {
console.error('Async: Could not copy text: ', err);
});
}
var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
copyJaneBtn = document.querySelector('.js-copy-jane-btn');
copyBobBtn.addEventListener('click', function(event) {
copyTextToClipboard('Bob');
});
copyJaneBtn.addEventListener('click', function(event) {
copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
<button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
<button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
<textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:
</textarea>
</div>
(codepen.io 예제가 작동하지 않을 수 있습니다. 위의 "중요한"참고 사항을 읽으십시오)이 스 니펫은 Stack Overflow의 내장 미리보기에서 제대로 작동하지 않습니다. https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors = 1011
비동기 클립 보드 API
Chrome 66의 권한 API를 통해 '권한을 요청'하고 클립 보드에 대한 액세스를 테스트하는 기능이 있습니다.
var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
console.log('Async: Copying to clipboard was successful!');
}, function(err) {
console.error('Async: Could not copy text: ', err);
});
document.execCommand ( 'copy')
이 포스트의 나머지 부분은 document.execCommand('copy')
API 의 미묘한 차이와 세부 사항에 대해 설명 합니다.
브라우저 지원
JavaScript document.execCommand('copy')
지원이 커졌습니다. 브라우저 업데이트는 아래 링크를 참조하십시오.
간단한 예
(이 사이트에 포함되어 작동하지 않을 수 있습니다. 위의 "중요"참고 사항을 읽으십시오)
var copyTextareaBtn = document.querySelector('.js-textareacopybtn');
copyTextareaBtn.addEventListener('click', function(event) {
var copyTextarea = document.querySelector('.js-copytextarea');
copyTextarea.focus();
copyTextarea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
} catch (err) {
console.log('Oops, unable to copy');
}
});
<p>
<button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
<textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>
복잡한 예 : 입력을 표시하지 않고 클립 보드에 복사
위의 간단한 예는 화면에 textarea
또는 input
요소가 표시되어 있으면 효과적 입니다.
경우에 따라 input
/ textarea
요소 를 표시하지 않고 클립 보드에 텍스트를 복사 할 수 있습니다 . 이 문제를 해결하는 방법의 한 예입니다 (기본적으로 요소 삽입, 클립 보드에 복사, 요소 제거).
Chrome 44, Firefox 42.0a1 및 Internet Explorer 11.0.8600.17814에서 테스트되었습니다.
(이 사이트에 포함되어 작동하지 않을 수 있습니다. 위의 "중요"참고 사항을 읽으십시오)
function copyTextToClipboard(text) {
var textArea = document.createElement("textarea");
//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a
// flash, so some of these are just precautions. However in
// Internet Explorer the element is visible whilst the popup
// box asking the user for permission for the web page to
// copy to the clipboard.
//
// Place in top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;
// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
// Avoid flash of white box if rendered for any reason.
textArea.style.background = 'transparent';
textArea.value = text;
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
} catch (err) {
console.log('Oops, unable to copy');
}
document.body.removeChild(textArea);
}
var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
copyJaneBtn = document.querySelector('.js-copy-jane-btn');
copyBobBtn.addEventListener('click', function(event) {
copyTextToClipboard('Bob');
});
copyJaneBtn.addEventListener('click', function(event) {
copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
<button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
<button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
<textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:
</textarea>
</div>
추가 사항
사용자가 조치를 취한 경우에만 작동
document.execCommand('copy')
클릭 이벤트 핸들러와 같은 사용자 작업의 직접적인 결과로 모든 호출이 이루어져야합니다. 이는 사용자 클립 보드가 예상하지 못한 경우 사용자의 클립 보드가 엉망이되는 것을 방지하기위한 조치입니다.
자세한 내용은 여기 에서 Google 개발자 게시물 을 참조하십시오.
클립 보드 API
전체 클립 보드 API 초안 사양은 https://w3c.github.io/clipboard-apis/ 에서 확인할 수 있습니다.
지원됩니까?
document.queryCommandSupported('copy')
true
"브라우저에서 지원하는"명령이면 반환 해야합니다.
- 및
document.queryCommandEnabled('copy')
반환 true
(가) 경우 document.execCommand('copy')
지금이라고하면 성공합니다. 사용자 시작 스레드에서 명령이 호출되었고 다른 요구 사항이 충족되는지 확인
그러나 브라우저 호환성 문제의 예로, ~ 4 월에서 ~ 10 월 2015까지 Chrome 은 명령이 사용자 시작 스레드에서 호출 된 경우 에만 반환 true
되었습니다 document.queryCommandSupported('copy')
.
아래의 호환성 세부 사항에 유의하십시오.
브라우저 호환성 세부 사항
사용자 클릭의 결과로 호출 document.execCommand('copy')
된 try
/ catch
블록 으로 래핑 된 간단한 호출 은 당신에게 가장 호환성을 제공하지만 다음과 같은 조항이 있습니다.
어느 전화 document.execCommand
, document.queryCommandSupported
또는이 document.queryCommandEnabled
A의 포장되어야한다 try
/ catch
블록.
서로 다른 브라우저 구현과 브라우저 버전은 return 대신에 호출 될 때 다른 유형의 예외를 발생 false
시킵니다.
다른 브라우저 구현은 여전히 유동적이며 클립 보드 API 는 아직 초안이므로 테스트를 수행해야합니다.