Câu hỏi Làm thế nào để sao chép vào clipboard trong JavaScript?


Cách tốt nhất để sao chép văn bản vào clipboard là gì? (đa trình duyệt)

Tôi đã thử:

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);
    }
}

nhưng trong Internet Explorer, nó đưa ra một lỗi cú pháp. Trong Firefox, nó nói unsafeWindow is not defined.

Một mẹo hay mà không cần flash: Trello truy cập clipboard của người dùng như thế nào?


2670
2017-12-30 13:09


gốc


Không có gì đặc biệt. Họ có thể tự làm nhưng tôi cũng muốn cung cấp khả năng nhấp vào một nút mà không phải lo lắng về việc chọn đúng phần văn bản. - Santiago Corredoira
có thể trùng lặp Đặt văn bản vào khay nhớ tạm với FireFox, Safari và Chrome - GvS
Bài đăng trên blog dài này chứa rất nhiều cách để thực hiện việc này: Truy cập Clipboard hệ thống bằng JavaScript - Chén Thánh? - Aaron Digulla
Nó cung cấp cho trình duyệt không xác định ngoại lệ trong IE cũng như trong FF - Jagadeesh
Nếu chúng ta có thể đưa văn bản vào khay nhớ tạm của người dùng, chúng ta có thể làm hỏng khay nhớ tạm của anh ấy. - Frank Fang


Các câu trả lời:


Tổng quan

Có 3 API trình duyệt chính để sao chép vào khay nhớ tạm:

  1. API Clipboard không đồng bộ  [navigator.clipboard.writeText]
    • Phần tập trung vào văn bản có sẵn trong Chrome 66 (tháng 3 năm 2018)
    • Quyền truy cập không đồng bộ và sử dụng Lời hứa JavaScript, có thể được viết để nhắc nhở người dùng bảo mật (nếu được hiển thị) không làm gián đoạn JavaScript trong trang.
    • Văn bản có thể được sao chép vào clipboard trực tiếp từ một biến.
    • Chỉ được hỗ trợ trên các trang được phân phối qua HTTPS.
    • Trong Chrome 66 trang trong tab đang hoạt động có thể ghi vào khay nhớ tạm mà không có lời nhắc cấp quyền.
  2. document.execCommand('copy')
    • Hầu hết các trình duyệt đều hỗ trợ tính năng này kể từ tháng 4 năm 2015 (xem Hỗ trợ trình duyệt bên dưới).
    • Truy cập đồng bộ, tức là dừng JavaScript trong trang cho đến khi hoàn thành bao gồm hiển thị và người dùng tương tác với bất kỳ lời nhắc bảo mật nào.
    • Văn bản được đọc từ DOM và được đặt vào khay nhớ tạm.
    • Trong thời gian thử nghiệm ~ tháng 4 năm 2015, chỉ có Internet Explorer được ghi chú là hiển thị các nhắc nhở quyền trong khi ghi vào khay nhớ tạm.
  3. Ghi đè sự kiện sao chép
    • Xem tài liệu API Clipboard trên Ghi đè sự kiện sao chép.
    • Cho phép bạn sửa đổi những gì xuất hiện trên clipboard từ bất kỳ sự kiện sao chép nào, có thể bao gồm các định dạng dữ liệu khác ngoài văn bản thuần túy.
    • Không được đề cập ở đây vì nó không trả lời trực tiếp câu hỏi.

Ghi chú phát triển chung

Đừng mong đợi các lệnh liên quan đến clipboard để hoạt động trong khi bạn kiểm tra mã trong bảng điều khiển. Nói chung, trang bắt buộc phải hoạt động (API Clipboard không đồng bộ) hoặc yêu cầu tương tác của người dùng (ví dụ: nhấp chuột của người dùng) để cho phép (document.execCommand('copy')) để truy cập vào clipboard xem bên dưới để biết thêm chi tiết.

Async + Dự phòng

Do mức hỗ trợ của trình duyệt cho API Clipboard mới của Async, bạn có thể muốn dự phòng document.execCommand('copy') để có được mức độ phù hợp của trình duyệt tốt.

Đây là một ví dụ đơn giản:

function fallbackCopyTextToClipboard(text) {
  var textArea = document.createElement("textarea");
  textArea.value = text;
  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>

Lưu ý rằng đoạn mã này không hoạt động tốt trong bản xem trước được nhúng của StackOverflow, bạn có thể thử nó ở đây: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors=1011

API Clipboard không đồng bộ

Lưu ý rằng có khả năng "yêu cầu quyền" và kiểm tra quyền truy cập vào khay nhớ tạm qua API quyền trong Chrome 66.

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')

Phần còn lại của bài viết này đi vào các sắc thái và chi tiết của document.execCommand('copy') API.

Hỗ trợ trình duyệt

JavaScript document.execCommand('copy') hỗ trợ đã phát triển, hãy xem các liên kết bên dưới để cập nhật trình duyệt:

Ví dụ đơn giản

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>

Ví dụ phức tạp: Sao chép vào clipboard mà không hiển thị đầu vào

Ví dụ đơn giản ở trên hoạt động tuyệt vời nếu có textarea hoặc là input hiển thị trên màn hình.

Trong một số trường hợp, bạn có thể muốn sao chép văn bản vào khay nhớ tạm mà không hiển thị input / textarea thành phần. Đây là một ví dụ về một cách để làm việc xung quanh điều này (về cơ bản chèn phần tử, sao chép vào clipboard, loại bỏ phần tử):

Đã thử nghiệm với Google Chrome 44, Firefox 42.0a1 và IE 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 IE 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>

Ghi chú bổ sung

Chỉ hoạt động nếu người dùng thực hiện hành động

Tất cả các document.execCommand('copy') cuộc gọi phải diễn ra dưới dạng kết quả trực tiếp của hành động của người dùng, ví dụ: bấm xử lý sự kiện. Đây là một biện pháp để ngăn chặn rối tung với clipboard của người dùng khi họ không mong đợi nó.

Xem Nhà phát triển Google đăng ở đây để biết thêm thông tin.

API Clipboard

Lưu ý đặc tả dự thảo API Clipboard đầy đủ có thể được tìm thấy tại đây: https://w3c.github.io/clipboard-apis/

Nó có được hỗ trợ không?

  • document.queryCommandSupported('copy') nên quay trở lại true nếu lệnh "được trình duyệt hỗ trợ".
  • document.queryCommandEnabled('copy') trở về true nếu document.execCommand('copy') sẽ thành công nếu được gọi ngay bây giờ. Kiểm tra để đảm bảo lệnh được gọi từ một chuỗi do người dùng khởi tạo và các yêu cầu khác được đáp ứng.

Tuy nhiên, như một ví dụ về các vấn đề tương thích với trình duyệt, Google Chrome từ tháng 4 đến tháng 10 năm 2015 chỉ trở lại true từ document.queryCommandSupported('copy') nếu lệnh được gọi từ một chuỗi do người dùng khởi tạo.

Lưu ý chi tiết tương thích bên dưới.

Chi tiết tương thích trình duyệt

Trong khi một cuộc gọi đơn giản tới document.execCommand('copy') bọc trong một try/catch khối được gọi là kết quả của nhấp chuột của người dùng sẽ giúp bạn sử dụng khả năng tương thích nhất sau đây có một số điều khoản:

Mọi cuộc gọi đến document.execCommand, document.queryCommandSupported hoặc là document.queryCommandEnabled nên được bọc trong một try/catch khối.

Các phiên bản trình duyệt và phiên bản trình duyệt khác nhau ném các loại ngoại lệ khác nhau khi được gọi thay vì trả lại false.

Việc triển khai trình duyệt khác nhau vẫn còn trong thông lượng và API Clipboard vẫn còn trong bản nháp, vì vậy hãy nhớ thực hiện kiểm tra của bạn.


1593
2018-06-12 18:56



cách sao chép trực tiếp từ dữ liệu biến .i.e .: var str = "word"; ? - jscripter
@BubuDaba Tạo một ẩn giả <textarea> với JS, gắn nó vào document.body, đặt giá trị của nó thành biến và sử dụng nó theo tốc độ copyTextarea, sau đó xóa nó ngay sau khi nội dung được sao chép. - SeinopSys
Có bất kỳ điều gì cho Safari hoặc bất kỳ chỉ báo nào sẽ được triển khai trong Safari không? - www139
@AyaSalama điểm mấu chốt là hành động "sao chép" không thể diễn ra trừ khi nó xuất hiện cho trình duyệt mà người dùng đang thực hiện hành động. Người dùng sẽ không thể thực hiện hành động nếu phần tử được tạo kiểu với "display: none" vì chúng sẽ không thể nhìn thấy nó, cũng như không tương tác với nó. - Dean Taylor
Tính năng này có hoạt động trên iPhone Safari cho bất kỳ ai không? - SB2055


Tự động sao chép vào clipboard có thể nguy hiểm, do đó, hầu hết các trình duyệt (ngoại trừ IE) làm cho nó rất khó khăn. Cá nhân, tôi sử dụng thủ thuật đơn giản sau đây:

function copyToClipboard(text) {
  window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
}

Người dùng được hiển thị với hộp nhắc, nơi văn bản được sao chép đã được chọn. Bây giờ nó đủ để nhấn Ctrl+C và Đi vào (để đóng hộp) - và thì đấy!

Bây giờ hoạt động sao chép clipboard là SAFE, bởi vì người dùng thực hiện nó theo cách thủ công (nhưng theo một cách khá đơn giản). Tất nhiên, hoạt động trong tất cả các trình duyệt.

<button id="demo" onclick="copyToClipboard(document.getElementById('demo').innerHTML)">This is what I want to copy</button>

<script>
  function copyToClipboard(text) {
    window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
</script>


1195
2018-05-19 08:06



Nice trick - nhưng hãy nhớ nó là Cmd-C cho Mac - Casebash
Thông minh, nhưng điều này chỉ hỗ trợ một dòng. - Aram Kocharyan
Việc thay đổi chức năng "nhắc" thành một phương thức tùy chỉnh, thịt của mẹo là sử dụng trường nội dung có thể chỉnh sửa và chọn trước văn bản và không phá vỡ giao diện người dùng trình duyệt bằng cách thực thi người dùng lấy tự hành động. A ++ - Jon z
vẫn không sử dụng javascript để sao chép vào clipboard ^ _ ^ - RozzA
Lạ lùng là điều này nhận được 457 upvotes trong khi nó không trả lời câu hỏi: sao chép vào clipboard trong Javascript! - stevenvh


Cách tiếp cận sau hoạt động trong Chrome, Firefox, Internet Explorer và Edge và trong các phiên bản Safari gần đây (Hỗ trợ sao chép đã được thêm vào trong phiên bản 10 đã được phát hành vào tháng 10 năm 2016).

  • Tạo một vùng văn bản và đặt nội dung của nó thành văn bản bạn muốn sao chép vào khay nhớ tạm.
  • Nối văn bản vào DOM.
  • Chọn văn bản trong vùng văn bản.
  • Gọi document.execCommand ("copy")
  • Hủy bỏ các textarea từ dom.

Lưu ý: bạn sẽ không thấy vùng văn bản, vì nó được thêm vào và bị xóa trong cùng một lời gọi mã lệnh đồng bộ.

Một số điều cần lưu ý nếu bạn tự mình thực hiện:

  • Vì lý do bảo mật, điều này chỉ có thể được gọi từ một trình xử lý sự kiện, chẳng hạn như bấm (giống như với các cửa sổ đang mở).
  • IE sẽ hiển thị hộp thoại cho phép trong lần đầu tiên cập nhật clipboard.
  • IE và Edge sẽ cuộn khi vùng được lấy nét.
  • execCommand () có thể ném trong một số trường hợp.
  • Các dòng mới và các tab có thể bị nuốt trừ khi bạn sử dụng một vùng văn bản. (Hầu hết các bài viết dường như khuyên bạn nên sử dụng một div)
  • Textarea sẽ hiển thị trong khi hộp thoại IE được hiển thị, bạn cần phải ẩn nó hoặc sử dụng api clipboardData cụ thể của IE.
  • Trong các quản trị viên hệ thống IE có thể vô hiệu hóa API clipboard.

Hàm dưới đây sẽ xử lý tất cả các vấn đề sau đây một cách rõ ràng nhất có thể. Xin vui lòng để lại một bình luận nếu bạn tìm thấy bất kỳ vấn đề hoặc có bất cứ đề nghị để cải thiện nó.

// Copies a string to the clipboard. Must be called from within an 
// event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+, 
// Firefox 42+, Safari 10+, Edge and IE 10+.
// IE: The clipboard feature may be disabled by an administrator. By
// default a prompt is shown the first time the clipboard is 
// used (per session).
function copyToClipboard(text) {
    if (window.clipboardData && window.clipboardData.setData) {
        // IE specific code path to prevent textarea being shown while dialog is visible.
        return clipboardData.setData("Text", text); 

    } else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
        var textarea = document.createElement("textarea");
        textarea.textContent = text;
        textarea.style.position = "fixed";  // Prevent scrolling to bottom of page in MS Edge.
        document.body.appendChild(textarea);
        textarea.select();
        try {
            return document.execCommand("copy");  // Security exception may be thrown by some browsers.
        } catch (ex) {
            console.warn("Copy to clipboard failed.", ex);
            return false;
        } finally {
            document.body.removeChild(textarea);
        }
    }
}

https://jsfiddle.net/fx6a6n6x/


196
2017-11-26 00:03



Câu trả lời hay: hỗ trợ trình duyệt chéo, xử lý lỗi + dọn dẹp. Hiện tại, hỗ trợ mới cho queryCommandSupported, sao chép vào clipboard hiện khả thi trong Javascript và đây là câu trả lời được chấp nhận, thay vì 'window.prompt' ("Sao chép vào clipboard: Ctrl + C, Enter", văn bản). window.clipboardData được hỗ trợ trong IE9, vì vậy bạn nên thêm IE9 vào danh sách hỗ trợ trình duyệt và tôi nghĩ có thể là IE8 và trước đó, nhưng cần phải xác minh. - user627283
Ừ. IE 8/9 Nên ổn. Ứng dụng của chúng tôi không hỗ trợ chúng. Vì vậy tôi chưa thử nghiệm. IE ngừng hỗ trợ vào tháng 1, vì vậy tôi không quá phiền phức. Hy vọng rằng hỗ trợ Safari sẽ sớm hạ cánh. Tôi chắc chắn nó trên radar của họ. - Greg Lowe
@SantiagoCorredoira: Trong năm 2016, điều này xứng đáng là câu trả lời được chấp nhận. Xin vui lòng xem xét phân công lại BGT (đánh dấu màu xanh lá cây lớn). - Lawrence Dol
@Noitidart Tôi đã thử nghiệm và nó hoạt động hoàn hảo cho firefox 54, chrome 60 và trình duyệt cạnh, ngay cả khi tiêu điểm không có trong tài liệu html, lỗi bạn đang gặp phải có thể dành riêng cho phiên bản FF 55 - Tosin John
@Noitidart Nó vẫn hoạt động hoàn hảo ở đây, tập trung vào các công cụ dev đã không ngăn chặn nó. Và nhân tiện, người dùng ứng dụng web thông thường sẽ làm gì trên các công cụ dành cho nhà phát triển - Tosin John


Nếu bạn muốn có một giải pháp thực sự đơn giản (mất ít hơn 5 phút để tích hợp) và có vẻ tốt trong hộp, thì Clippy là một lựa chọn tốt cho một số giải pháp phức tạp hơn.

Clippy

Nó được viết bởi một người đồng sáng lập của Github. Ví dụ về mã nhúng Flash bên dưới:

<object 
   classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
   width="110"
   height="14"
   id="clippy">
  <param name="movie" value="/flash/clippy.swf"/>
  <param name="allowScriptAccess" value="always"/>
  <param name="quality" value="high"/>
  <param name="scale" value="noscale"/>
  <param NAME="FlashVars" value="text=#{text}"/>
  <param name="bgcolor" value="#{bgcolor}"/>
  <embed 
     src="/flash/clippy.swf"
     width="110"
     height="14"
     name="clippy"
     quality="high"
     allowScriptAccess="always"
     type="application/x-shockwave-flash"
     pluginspage="http://www.macromedia.com/go/getflashplayer"
     FlashVars="text=#{text}"
     bgcolor="#{bgcolor}"/>
</object>

Nhớ thay thế #{text} với văn bản bạn cần sao chép và #{bgcolor} với màu sắc.


93
2017-10-17 14:40



Đối với bất kỳ ai quan tâm, hãy kiểm tra Clippy đang được sử dụng trên GitHub khi sao chép URL cho repo. - Radek
FYI, việc sử dụng Clippy trên GitHub đã được thay thế bởi ZeroClipboard. - James M. Greene
OP muốn có một giải pháp trong JavaScript. Không flash. - MT.
@MT, bởi "javascript" một số người có nghĩa là "trong trình duyệt của khách hàng", vì vậy trong khi JS-chỉ có thể là một yêu cầu, nhiều người trong số những người cơ hội khi câu trả lời này thực sự đang tìm kiếm JS-hoặc-khác-được hỗ trợ rộng rãi- khách hàng công nghệ. Flash không tấn công tất cả các nền tảng, nhưng đối với một tính năng đánh bóng như hỗ trợ clipboard, nó là giá trị bổ sung nếu nó cải thiện UX trên một hộp thoại bật lên (mà nó chắc chắn không). - Dave Dopson
Bởi bây giờ dựa vào Flash có nghĩa là có những thứ không làm việc cho một tỷ lệ phần trăm của khách truy cập trang web đó là không thể chấp nhận cho gần như tất cả mọi người làm phát triển web. - jinglesthula


Đọc và sửa đổi clipboard từ một trang web làm tăng mối quan tâm về bảo mật và quyền riêng tư. Tuy nhiên, trong Internet Explorer, nó có thể làm điều đó. tôi đã tìm thấy cái này đoạn mã ví dụ:

    <script type="text/javascript">
        function select_all(obj) {
            var text_val=eval(obj);
            text_val.focus();
            text_val.select();
            r = text_val.createTextRange();
            if (!r.execCommand) return; // feature detection
            r.execCommand('copy');
        }
    </script>
    <input value="http://www.sajithmr.com"
     onclick="select_all(this)" name="url" type="text" />


78
2017-12-30 13:33



Sử dụng đèn flash cho một thao tác sao chép đơn giản có vẻ như quá mức cần thiết, vui vì có một cách JS rõ ràng để thực hiện việc này. Và kể từ khi chúng tôi đang ở trong một công ty env. IE là tốt. Cảm ơn Bandi! - Eddie
plz giải thích những gì execCommand(\\’copy\\’); sao, nếu không sao chép vào clipboard cho IE? @mrBorna - RozzA
hoạt động tốt trong IE7-IE9, cảm ơn bạn! - luschn
Không được dùng if(!document.all) nhưng if(!r.execCommand) vì sợ ai khác thực hiện nó! Document.all hoàn toàn không liên quan đến điều này. - m93a
Người đàn ông, đây là những gì tôi yêu về mã đơn giản và sạch sẽ, nó hoạt động gần như mãi mãi với bảo trì nhỏ. Điều này đã làm cho tôi, Nó hoạt động rất đẹp. - Samuel Ramzan


Gần đây tôi đã viết một bài đăng blog kỹ thuật về vấn đề này (tôi làm việc tại Lucidchart và gần đây chúng tôi đã thực hiện một sửa chữa lớn trên clipboard).

Sao chép văn bản thuần vào clipboard là tương đối đơn giản, giả sử bạn muốn thực hiện nó trong một sự kiện sao chép hệ thống (người dùng nhấn CtrlC hoặc sử dụng trình đơn của trình duyệt).

var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 
           || navigator.userAgent.toLowerCase().indexOf("trident") != -1);

document.addEventListener('copy', function(e) {
    var textToPutOnClipboard = "This is some text";
    if (isIe) {
        window.clipboardData.setData('Text', textToPutOnClipboard);    
    } else {
        e.clipboardData.setData('text/plain', textToPutOnClipboard);
    }
    e.preventDefault();
});

Việc đặt văn bản trên khay nhớ tạm thời không phải trong một sự kiện sao chép hệ thống sẽ khó khăn hơn nhiều. Có vẻ như một số câu trả lời khác tham khảo các cách để thực hiện điều đó thông qua Flash, đây là cách duy nhất để duyệt qua (theo như tôi hiểu).

Ngoài ra, có một số tùy chọn trên cơ sở trình duyệt theo trình duyệt.

Đây là cách đơn giản nhất trong IE, nơi bạn có thể truy cập đối tượng clipboardData bất cứ lúc nào từ JavaScript qua:

window.clipboardData

(Khi bạn cố gắng thực hiện điều này bên ngoài hệ thống bị cắt, sao chép hoặc dán sự kiện, tuy nhiên, IE sẽ nhắc người dùng cấp quyền tạm ứng cho ứng dụng web.)

Trong Chrome, bạn có thể tạo tiện ích mở rộng của Chrome sẽ cung cấp cho bạn giấy phép clipboard (đây là những gì chúng tôi làm cho Lucidchart). Sau đó, đối với người dùng đã cài đặt tiện ích mở rộng của bạn, bạn chỉ cần tự mình kích hoạt sự kiện hệ thống:

document.execCommand('copy');

Có vẻ như Firefox có một số tùy chọn cho phép người dùng cấp quyền cho các trang web nhất định để truy cập vào khay nhớ tạm, nhưng tôi chưa thử bất kỳ cá nhân nào trong số này.


65
2017-12-03 20:31



Không được đề cập trong bài đăng trên blog (Tôi hy vọng sẽ cập nhật nó trong tương lai gần), là khả năng kích hoạt cắt và sao chép bằng cách sử dụng execCommand. Điều này được hỗ trợ trong IE10 +, Chrome 43+ và Opera29 +. Đọc về nó ở đây. updates.html5rocks.com/2015/04/cut-and-copy-commands - Richard Shurtz
Một vấn đề với điều này là nó chiếm đoạt các sự kiện sao chép bình thường khác. - Brock Adams


clipboard.js là một tiện ích nhỏ, không flash, cho phép sao chép dữ liệu văn bản hoặc html vào clipboard. Nó rất dễ sử dụng, chỉ cần bao gồm .js và sử dụng một cái gì đó như thế này:

<button id='markup-copy'>Copy Button</button>

<script>
document.getElementById('markup-copy').addEventListener('click', function() {
  clipboard.copy({
    'text/plain': 'Markup text. Paste me into a rich text editor.',
    'text/html': '<i>here</i> is some <b>rich text</b>'
  }).then(
    function(){console.log('success'); },
    function(err){console.log('failure', err);
  });

});
</script>

clipboard.js cũng bật GitHub


44
2017-08-11 15:33



Thư viện này được sử dụng bởi angular.io cho Tour of Hero và dự phòng của nó ở chế độ duyên dáng cho trình duyệt không hỗ trợ execCommand bằng cách hiển thị văn bản được chọn trước mà người dùng vừa sao chép. - John-Philip


ZeroClipboard là giải pháp trình duyệt chéo tốt nhất mà tôi đã tìm thấy:

<div id="copy" data-clipboard-text="Copy Me!">Click to copy</div>    
<script src="ZeroClipboard.js"></script>
<script>
  var clip = new ZeroClipboard( document.getElementById('copy') );
</script>

Nếu bạn cần hỗ trợ không phải flash cho iOS, bạn chỉ cần thêm một phần bổ sung:

clip.on( 'noflash', function ( client, args ) {
    $("#copy").click(function(){            
        var txt = $(this).attr('data-clipboard-text');
        prompt ("Copy link, then click OK.", txt);
    });
});  

http://zeroclipboard.org/

https://github.com/zeroclipboard/ZeroClipboard


35
2017-11-21 20:41



trình duyệt chéo với Flash? không hoạt động trên iOS và Android 4.4 - Raptor
Xem câu trả lời được cập nhật. Điều này cho phép các bước ít hơn cho người dùng flash và sự sụt giảm cho mọi người khác. - Justin
nó có một tỷ dòng mã. nó hoàn toàn nhạo báng. tốt hơn là không nên làm điều đó hơn là bao gồm một con quái vật như vậy trong một dự án - vsync
Có một phiên bản đơn giản gist.github.com/JamesMGreene/8698897 đó là 20K mà không có tất cả các chuông và còi trong phiên bản 74k. Không phải là rất lớn. Đoán của tôi là hầu hết người dùng đều ổn với thêm mili giây mà một tệp 74k hoặc 20k đang được tải xuống sẽ mất sao chép / dán là một cú nhấp chuột thay vì hai. - Justin
@ Justin Tôi không thể làm cho nó hoạt động cục bộ, ngay cả khi tôi sao chép và dán các ví dụ (tôi thực hiện các thay đổi tối thiểu, ví dụ: giá trị của src trong các thẻ tập lệnh). Tôi cảm thấy rằng tài liệu của họ là khá nhưng không hiệu quả. - Gui Imamura


Đây là của tôi đi trên đó ..

function copy(text) {
    var input = document.createElement('input');
    input.setAttribute('value', text);
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input)
    return result;
 }

30
2017-09-14 09:20



Làm việc trong lần thử đầu tiên. Chúc mừng. - JustAGuy
Rất vui được nghe tôi đã giúp. - nikksan
Làm việc như say mê, cảm ơn sự giúp đỡ. +1 - FONGOH MARTIN
@nikksan cách sao chép chuỗi bằng \n? - sof-03
Không hoạt động trong Microsoft Edge 42.17134.1.0 trên Win10x64 - Honsa Stunna


Từ một trong những dự án tôi đã làm việc trên, một plugin jQuery copy-to-clipboard sử dụng Không Clipboard thư viện.

Nó dễ sử dụng hơn plugin Zero Clipboard gốc nếu bạn là người dùng jQuery nặng.


25
2018-05-03 22:17



92kb không phải là tất cả những gì thực sự lớn, nó hoạt động nhanh và bạn có thể sử dụng text() thay vì innerHTML() nếu bạn thích.. - RozzA
@John: innerHTML đã được hỗ trợ qua trình duyệt trong một thời gian dài. Chỉ vì Microsoft ban đầu đã đưa ra ý tưởng nó không làm cho nó không đáng tin cậy hoặc độc quyền. Nó cũng là bây giờ cuối cùng được thêm vào thông số chính thức (sau khi mọi nhà cung cấp trình duyệt chính đã thêm hỗ trợ cho nó ... thở dài). - James M. Greene
@ John Bạn phàn nàn về jQuery không đủ JavaScripty trong câu trả lời sử dụng Flash;) - Max Nanasy
innerHTML tốt hơn các lựa chọn thay thế trong hầu hết các trường hợp. Cút ngựa cao của bạn! Nó nhanh hơn, hiệu quả hơn và không yêu cầu phải trả lại trang. - Orbiting Eden
@RozzA 92KB thực sự lớn. Cho đến LTE matures GPRS là Tiêu chuẩn dữ liệu di động của WWvà nó bắt đầu lúc 1 KB/s. Tự mình làm toán. - Tino


Tôi tìm thấy giải pháp sau:

Trên trình xử lý khóa, tạo thẻ "trước". Chúng tôi đặt nội dung để sao chép vào thẻ này, sau đó thực hiện lựa chọn trên thẻ này và trả về true trong trình xử lý. Điều này gọi trình xử lý tiêu chuẩn của chrome và sao chép văn bản đã chọn.

Và nếu bạn cần bạn có thể đặt thời gian chờ cho chức năng để khôi phục lựa chọn trước đó. Việc triển khai của tôi trên Mootools:

   function EnybyClipboard() {
     this.saveSelection = false;
     this.callback = false;
     this.pastedText = false;

     this.restoreSelection = function() {
       if (this.saveSelection) {
         window.getSelection().removeAllRanges();
         for (var i = 0; i < this.saveSelection.length; i++) {
           window.getSelection().addRange(this.saveSelection[i]);
         }
         this.saveSelection = false;
       }
     };

     this.copyText = function(text) {
       var div = $('special_copy');
       if (!div) {
         div = new Element('pre', {
           'id': 'special_copy',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
       }
       div.set('text', text);
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         setTimeout(this.restoreSelection.bind(this), 100);
       } else return alert('Copy not work. :(');
     };

     this.getPastedText = function() {
       if (!this.pastedText) alert('Nothing to paste. :(');
       return this.pastedText;
     };

     this.pasteText = function(callback) {
       var div = $('special_paste');
       if (!div) {
         div = new Element('textarea', {
           'id': 'special_paste',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
         div.addEvent('keyup', function() {
           if (this.callback) {
             this.pastedText = $('special_paste').get('value');
             this.callback.call(null, this.pastedText);
             this.callback = false;
             this.pastedText = false;
             setTimeout(this.restoreSelection.bind(this), 100);
           }
         }.bind(this));
       }
       div.set('value', '');
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         div.focus();
         this.callback = callback;
       } else return alert('Fail to paste. :(');
     };
   }

Sử dụng:

enyby_clip = new EnybyClipboard(); //init 

enyby_clip.copyText('some_text'); // place this in CTRL+C handler and return true;

enyby_clip.pasteText(function callback(pasted_text) {
        alert(pasted_text);
}); // place this in CTRL+V handler and return true;

Khi dán nó tạo ra vùng văn bản và hoạt động theo cùng một cách.

PS có thể là giải pháp này có thể được sử dụng để tạo ra giải pháp hoàn toàn qua trình duyệt mà không cần flash. Các tác phẩm của nó trong FF và Chrome.


21
2017-07-05 15:33



Có ai đã thử điều đó không? Nghe có vẻ giống như một thingy tiện lợi, trong trường hợp nó thực sự hoạt động trên một loạt các trình duyệt! - Michael
Tôi có sáu tháng làm việc đúng cách trong đơn của tôi. - Enyby
Firefox hiển thị: 'SecurityError: Thao tác không an toàn.' - Adrian Florescu
Phiên bản Firefox? Dòng nơi lỗi xuất hiện? - Enyby
jsfiddle.net/H2FHC Bản giới thiệu: fiddle.jshell.net/H2FHC/show Vui lòng mở nó và nhấn Ctrl + V hoặc Ctrl + C. Trong FF 19.0 dĩa hoàn hảo. Trong Chrome 25.0.1364.97 m nữa. Opera 12.14 - OK. Safari 5.1.7 dành cho Windows - OK. IE - FAIL. - Enyby