프로그래밍 언어/JAVA

JavaScript에서 클립 보드에 복사하는 방법

Rateye 2021. 10. 14. 12:14
728x90
반응형
질문 : JavaScript에서 클립 보드에 복사하려면 어떻게합니까?

텍스트를 클립 보드 (다중 브라우저)에 복사하는 가장 좋은 방법은 무엇입니까?

나는 시도했다 :

function copyToClipboard(text) {
    if (window.clipboardData) { // Internet Explorer
        window.clipboardData.setData("Text", text);
    } else {
        unsafeWindow.netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        const clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
        clipboardHelper.copyString(text);
    }
}

그러나 Internet Explorer에서는 구문 오류가 발생합니다. Firefox에서는 unsafeWindow가 정의되지 않았습니다 .

Flash 를 사용하지 않는 멋진 트릭 : Trello는 사용자의 클립 보드에 어떻게 액세스합니까?

답변

클립 보드에 복사하기위한 세 가지 기본 브라우저 API가 있습니다.

  1. 비동기 클립 보드 API [navigator.clipboard.writeText]
    • Chrome 66에서 사용할 수있는 텍스트 중심 부분 (2018 년 3 월)
    • 액세스는 비동기식이며 JavaScript Promises를 사용하며 보안 사용자 프롬프트 (표시된 경우)가 페이지의 JavaScript를 중단하지 않도록 작성할 수 있습니다.
    • 텍스트는 변수에서 직접 클립 보드로 복사 할 수 있습니다.
    • HTTPS를 통해 제공되는 페이지에서만 지원됩니다.
    • Chrome 66 페이지에서 비활성 탭은 권한 프롬프트없이 클립 보드에 쓸 수 있습니다.
  2. document.execCommand('copy')
    • 대부분의 브라우저는 2015 년 4 월부터이를 지원합니다 (아래 브라우저 지원 참조).
    • 액세스는 동기식입니다. 즉, 보안 프롬프트 표시 및 사용자 상호 작용을 포함하여 완료 될 때까지 페이지에서 JavaScript를 중지합니다.
    • DOM에서 텍스트를 읽어 클립 보드에 배치합니다.
    • 2015 년 4 월까지 테스트하는 동안 Internet Explorer 만 클립 보드에 쓰는 동안 권한 프롬프트를 표시하는 것으로 나타났습니다.
  3. 복사 이벤트 재정의
    • 복사 이벤트 재정의에 대한 클립 보드 API 설명서를 참조하십시오.
    • 복사 이벤트에서 클립 보드에 나타나는 내용을 수정할 수 있으며 일반 텍스트 이외의 다른 형식의 데이터를 포함 할 수 있습니다.
    • 질문에 직접 답하지 않기 때문에 여기서는 다루지 않습니다.

 

일반 개발 참고 사항

콘솔에서 코드를 테스트하는 동안 클립 보드 관련 명령이 작동 할 것으로 기대하지 마십시오. 일반적으로 페이지는 활성 상태 (Async Clipboard API)이거나 사용자 상호 작용 (예 : 사용자 클릭)이 document.execCommand('copy') ). 자세한 내용은 아래를 참조하십시오.

중요 (noted here 2020/02/20)

이 게시물은 원래 교차 출처 IFRAME 및 기타 IFRAME "샌드 박싱" 에서 권한 사용 중단으로 작성되었으므로 포함 된 데모 "코드 스 니펫 실행"버튼 및 "codepen.io 예제"가 일부 브라우저 (Chrome 및 Microsoft Edge 포함)에서 작동하지 않습니다. ).

자체 웹 페이지를 개발하려면 HTTPS 연결을 통해 해당 페이지를 제공하여 테스트하고 개발하십시오.

다음은 코드 작동을 보여주는 테스트 / 데모 페이지입니다 : https://deanmarktaylor.github.io/clipboard-test/

Async + Fallback

새로운 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

Async Clipboard 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의 뉘앙스와 세부 사항에 대해 설명합니다.

Browser Support

JavaScript document.execCommand('copy') 지원이 증가했습니다. 브라우저 업데이트는 아래 링크를 참조하십시오.

Simple Example

(이 사이트에 임베드 된 기능이 작동하지 않을 수 있습니다. 위의 "중요"참고 사항을 읽으십시오)

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 요소를 표시하지 않고 텍스트를 클립 보드에 복사 할 수 있습니다. 다음은이 문제를 해결하는 방법의 한 가지 예입니다 (기본적으로 요소 삽입, 클립 보드에 복사, 요소 제거).

Google 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 the 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 the 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 the 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 개발자 게시물 을 참조하세요.

전체 Clipboard API 초안 사양은 https://w3c.github.io/clipboard-apis/에서 찾을 수 있습니다.

  • document.queryCommandSupported('copy') 는 "브라우저에서 지원하는"명령 인 경우 true 를 반환해야합니다.
  • 그리고 document.queryCommandEnabled('copy')document.execCommand('copy') 가 지금 호출되면 성공하면 true 반환합니다. 사용자가 시작한 스레드에서 명령이 호출되었으며 기타 요구 사항이 충족되는지 확인합니다.

그러나 브라우저 호환성 문제의 예로, 2015 년 4 월부터 10 월까지의 Chrome은 사용자가 시작한 스레드에서 명령이 호출 된 경우 document.queryCommandSupported('copy') true 를 반환했습니다.

아래에서 호환성 세부 정보를 확인하십시오.

브라우저 호환성 세부 정보

try / catch 블록에 래핑 된 document.execCommand('copy') 대한 간단한 호출은 가장 호환성이 뛰어난 반면 다음과 같은 몇 가지 단서가 있습니다.

document.execCommand , document.queryCommandSupported 또는 document.queryCommandEnabled 에 대한 모든 호출 try / catch 블록에 래핑되어야합니다.

false 를 반환하는 대신 호출 될 때 다른 유형의 예외를 발생시킵니다.

다른 브라우저 구현은 여전히 유동적이며 Clipboard API 는 아직 초안이므로 테스트를 수행해야합니다.

출처 : https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript
728x90
반응형