Làm cách nào để sao chép vào bảng tạm trong JavaScript?


3322

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?


Chỉ tò mò, bạn muốn sao chép cái gì vào clipboard mà người dùng không thể tự làm được?
scunliffe

233
Không có gì đặc biệt. Họ có thể tự làm điều đó nhưng tôi cũng muốn cung cấp khả năng nhấp vào nút mà không cần lo lắng về việc chọn đúng phần văn bản.
Santiago Corredoira

4
Bài đăng blog dài này chứa rất nhiều cách để làm điều này: Truy cập Bảng tạm hệ thống bằng JavaScript - Chén thánh?
Aaron Digulla

Nó đang cung cấp cho trình duyệt ngoại lệ không xác định trong IE cũng như trong FF
Jagadeesh

1
Nếu chúng ta có thể đặt văn bản vào clipboard của người dùng, chúng ta có thể phá hỏng clipboard của anh ấy.
Frank Fang

Câu trả lời:


2249

Tổng quat

Có ba API trình duyệt chính để sao chép vào bảng tạm:

  1. API Clipboard Async [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 để lời nhắc của 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ục vụ qua HTTPS.
    • Trong Chrome 66 trang trong các tab hoạt động có thể ghi vào bảng tạm mà không cần nhắc nhở quyền.
  2. document.execCommand('copy')
    • Hầu hết các trình duyệt hỗ trợ này kể từ ~ tháng 4 năm 2015 (xem Hỗ trợ trình duyệt bên dưới).
    • Truy cập là đồng bộ, tức là dừng JavaScript trong trang cho đến khi hoàn tất 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 trên bảng tạm.
    • Trong quá trình thử nghiệm ~ tháng 4 năm 2015, chỉ có Internet Explorer được ghi nhận là hiển thị lời nhắc cấp phép trong khi ghi vào bảng tạm.
  3. Ghi đè sự kiện sao chép
    • Xem tài liệu API của Clipboard về Ghi đè sự kiện sao chép .
    • Cho phép bạn sửa đổi những gì xuất hiện trên bảng tạm 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 sẽ hoạt động trong khi bạn đang kiểm tra mã trong bảng điều khiển. Nói chung, trang bắt buộc phải hoạt động (Async Clipboard API) hoặc yêu cầu tương tác 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 bảng tạm xem bên dưới để biết thêm chi tiết.

QUAN TRỌNG (lưu ý ở đây 2020/02/20)

Lưu ý rằng vì bài đăng này ban đầu được viết là không chấp nhận các quyền trong IFRAME có nguồn gốc chéo"hộp cát" IFRAME khác ngăn các trình diễn nhúng "Chạy đoạn mã" và "ví dụ codepen.io" hoạt động trong một số trình duyệt (bao gồm cả Chrome và Microsoft Edge ).

Để phát triển tạo trang web của riêng bạn, hãy phân phát trang đó qua kết nối HTTPS để kiểm tra và phát triển.

Đây là trang thử nghiệm / bản demo cho thấy mã đang hoạt động: https://deanmarktaylor.github.io/clipboard-test/

Không đồng bộ + Dự phòng

Do mức độ hỗ trợ trình duyệt cho API Clipboard Async mới, bạn có thể muốn quay lại document.execCommand('copy')phương thức để có được phạm vi bảo hiểm tốt của trình duyệt.

Dưới đây là một ví dụ đơn giản (có thể không hoạt động được nhúng trong trang web này, hãy đọc ghi chú "quan trọng" ở trên):

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 dụ có thể không làm việc, đọc lưu ý "quan trọng" ở trên) Lưu ý rằng đoạn mã này không hoạt động tốt trong preview nhúng Stack Overflow của bạn có thể thử nó ở đây: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors = 1011

API Clipboard Async

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 bảng tạm thông 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 ('bản sao')

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

Hỗ trợ trình duyệt

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

Ví dụ đơn giản

(có thể không hoạt động được nhúng trong trang web này, đọc ghi chú "quan trọng" ở trê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ó một textareahoặc inputphần tử 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 bảng tạm mà không hiển thị phần tử input/ textarea. Đây là một ví dụ về cách khắc phục điều này (về cơ bản chèn phần tử, sao chép vào bảng tạm, xóa phần tử):

Đã thử nghiệm với Google Chrome 44, Firefox 42.0a1 và Internet Explorer 11.0.8600.17814.

(có thể không hoạt động được nhúng trong trang web này, đọc ghi chú "quan trọng" ở trên)

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>

Ghi chú bổ sung

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

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

Xem bài đăng của Nhà phát triển Google tại đây để biết thêm.

API bảng tạm

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

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

  • document.queryCommandSupported('copy')sẽ trả về truenếu lệnh "được trình duyệt hỗ trợ".
  • document.queryCommandEnabled('copy')trở lại truenế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 luồng 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ề vấn đề tương thích trình duyệt, Google Chrome từ tháng Tư đến ~ ~ Tháng 10 năm 2015 chỉ trở lại truetừ document.queryCommandSupported('copy')khi lệnh được gọi từ một sợi dùng bắt đầu.

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 document.execCommand('copy')được gói trong một khối try/ catchđược gọi là kết quả của một lần nhấp người dùng sẽ giúp bạn có được khả năng tương thích cao nhất, sau đây có một số điều khoản:

Bất kỳ cuộc gọi đến document.execCommand, document.queryCommandSupportedhoặc document.queryCommandEnablednên được gói trong một try/ catchkhối.

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

Các triển khai trình duyệt khác nhau vẫn còn thay đổi và API Clipboard vẫn còn trong dự thảo, vì vậy hãy nhớ thực hiện thử nghiệm của bạn.


41
Làm thế nào để sao chép trực tiếp từ một dữ liệu biến .ie : var str = "word";?
jscripter 7/07/2015

10
@BubuDaba Tạo một hình nộm ẩn <textarea>với JS, nối 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

3
Có bất cứ điều gì cho Safari hoặc bất kỳ chỉ số nào sẽ được thực hiện trong Safari không?
www139

3
Phiên bản duy nhất tôi tìm thấy hoạt động trong tất cả các trình duyệt. Tôi thấy khi sử dụng cái này trong Boostrap Modal, tôi phải nối vùng văn bản vào phương thức. Tôi sẽ cung cấp +1000 nếu tôi có thể cho giải pháp của bạn !!! CẢM ƠN!
Patrick

3
@AyaSalama điểm quan trọng là hành động "sao chép" không thể diễn ra trừ khi nó xuất hiện trên 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ì họ sẽ không thể nhìn thấy nó, cũng không tương tác với nó.
Dean Taylor

1257

Tự động sao chép vào clipboard có thể nguy hiểm, do đó hầu hết các trình duyệt (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:

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

Người dùng được trình bày với hộp nhắc nhở, trong đó văn bản sẽ được sao chép đã được chọn. Bây giờ đã đủ để nhấn Ctrl+ CEnter(để đóng hộp) - và thì đấy!

Bây giờ thao tác sao chép clipboard là AN TOÀN, bởi vì người dùng thực hiện thủ công (nhưng theo 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>


91
Thông minh, nhưng điều này chỉ hỗ trợ dòng duy nhất.
Aram Kocharyan

61
Việc thay đổi chức năng "prompt" thành một phương thức tùy chỉnh là rất đơn giản, mánh khóe lừa đả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à nó không phá vỡ giao diện người dùng trình duyệt bằng cách ép buộc người dùng thực hiện tự hành động. A ++
Jon z

110
vẫn không sử dụng javascript để sao chép vào clipboard ^ _ ^
RozzA

23
Nếu văn bản của bạn có hơn 2000 ký tự, nó sẽ bị cắt ngắn, nhưng đối với các mẫu văn bản nhỏ hơn thì nó hoạt động rất tốt
RasTheDestroyer

445
Điều kỳ lạ là điều này nhận được 457 lượt upvote trong khi nó không trả lời câu hỏi: sao chép vào bảng tạm trong Javascript !
stevenvh

299

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 gần đây của Safari (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 textarea và đặt nội dung của nó thành văn bản bạn muốn sao chép vào bảng tạm.
  • Nối văn bản vào DOM.
  • Chọn văn bản trong textarea.
  • Gọi tài liệu.execCommand ("bản sao")
  • Loại bỏ các textarea từ dom.

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

Một số điều cần chú ý nếu bạn đang tự thực hiện điều này:

  • 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ư nhấp chuột (Cũng giống như với việc mở các cửa sổ).
  • Internet Explorer sẽ hiển thị hộp thoại cấp phép trong lần đầu tiên bảng tạm được cập nhật.
  • Internet Explorer và Edge sẽ cuộn khi vùng văn bản được tập trung.
  • execCommand () có thể ném trong một số trường hợp.
  • Dòng mới và tab có thể bị nuốt trừ khi bạn sử dụng textarea. (Hầu hết các bài viết dường như khuyên bạn nên sử dụng div)
  • Textarea sẽ hiển thị trong khi hộp thoại Internet Explorer được hiển thị, bạn cần phải ẩn nó hoặc sử dụng API clipboardData cụ thể của Internet Explorer.
  • Trong Internet Explorer, quản trị viên có thể vô hiệu hóa API clipboard.

Các chức năng dưới đây sẽ xử lý tất cả các vấn đề sau càng sạch càng tốt. 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 kỳ đề 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 Internet Explorer 10+.
// Internet Explorer: 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) {
        // Internet Explorer-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 Microsoft 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/


9
Câu trả lời hay: hỗ trợ trình duyệt chéo, xử lý lỗi + dọn dẹp. Kể từ ngày nay, hỗ trợ mới cho queryCommandSupported, sao chép vào clipboard hiện khả thi trong Javascript và đây phải là câu trả lời được chấp nhận, thay vì lúng túng '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ể IE8 và trước đó cũng vậy, nhưng cần phải xác minh.
dùng627283

Vâng. IE 8/9 nên ok. Ứng dụng của chúng tôi không hỗ trợ họ. Vì vậy, tôi đã không thử nghiệm. IE ngừng hỗ trợ vào tháng 1, vì vậy tôi không quá bận tâm. Hy vọng hỗ trợ Safari sẽ sớm hạ cánh. Tôi chắc chắn rằng đó là trên radar của họ.
Greg Lowe

4
@SantiagoCorredoira: Năm 2016, đây xứng đáng là câu trả lời được chấp nhận. Vui lòng xem xét việc chỉ định lại BGT (đánh dấu lớn màu xanh lá cây).
Lawrence Dol

3
@Noitidart Tôi đã thử nghiệm và nó hoạt động hoàn hảo cho trình duyệt firefox 54, chrome 60 và edge, ngay cả khi tiêu điểm không có trong tài liệu html, lỗi bạn có thể gặp phải là phiên bản FF 55
Tosin John

2
@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 dừng lại. Và nhân tiện, một người dùng ứng dụng web bình thường sẽ làm gì trên các công cụ dành cho nhà phát triển
Tosin John

97

Đây là ý kiến ​​của tôi về điều đó ...

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

@korayem: Lưu ý rằng việc sử dụng inputtrường html sẽ không tôn trọng ngắt dòng \nvà sẽ làm phẳng bất kỳ văn bản nào thành một dòng.

Như @nikksan đã đề cập trong các nhận xét, sử dụng textareasẽ khắc phục sự cố như sau:

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

@nikksan làm thế nào để sao chép chuỗi với \n?
sof-03

2
@ sof-03 sử dụng textarea thay vì đầu vào và thêm \r\nđể ngắt dòng
nikksan

1
Không hoạt động trong Microsoft Edge 42.17134.1.0 trên Win10x64
Honsa Stunna

3
Tôi đã sao chép câu trả lời của bạn. Nó hoạt động trong chrome và đó là tất cả những gì tôi cần.
dùng875234

Đây là giải pháp đơn giản nhất hoạt động với Firefox v68.0.2 (64-bit).
Arya

88

Nếu bạn muốn 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 ngay lập tức, thì Clippy là một giải pháp thay thế tốt cho một số giải pháp phức tạp hơn.

Nó được viết bởi một người đồng sáng lập GitHub. Ví dụ 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>

Hãy nhớ thay thế #{text}bằng văn bản bạn cần sao chép và #{bgcolor}bằng một màu.


12
Đố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

66
FYI, việc sử dụng Clippy trên GitHub đã được thay thế bằng ZeroClipboard.
James M. Greene

219
OP muốn có một giải pháp trong JavaScript. Không flash.
MT.

21
@MT, bởi "javascript", một số người có nghĩa là "trong ứng dụng khách trình duyệt", do đó, trong khi chỉ có thể là một yêu cầu, nhiều người có cơ hội trả lời câu hỏi này thực sự đang tìm kiếm JS hoặc được người khác ủng hộ 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, đáng để thêm vào nếu nó cải thiện UX qua hộp thoại bật lên (điều này chắc chắn làm được).
Dave Dopson

13
Bởi bây giờ dựa vào Flash có nghĩa là có những thứ không hoạt động đối với một tỷ lệ khách truy cập trang web không thể chấp nhận được đối với gần như tất cả mọi người đang phát triển web.
jinglểula

86

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

    <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" />


7
Sử dụng flash cho một thao tác sao chép đơn giản có vẻ như quá mức cần thiết, rất vui vì có một cách JS rõ ràng để làm điều này. Và vì chúng tôi đang ở trong một env của công ty. IE là tốt. Cảm ơn Bandi!
Eddie

5
Xin vui lòng giải thích những gì execCommand(\\’copy\\’);không, nếu không sao chép vào clipboard cho IE? @mrBorna
RozzA

20
Không sử dụng if(!document.all)nhưng if(!r.execCommand)kẻo người khác thực hiện nó! Document.all hoàn toàn không liên quan đến điều này.
m93a

1
Man, đây là những gì tôi yêu thích 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 điều đó cho tôi, Nó hoạt động rất đẹp.
Samuel Ramzan

1
không hoạt động trong chrome, firefox hoặc MS Edge mới nhất :(
Jonathan Marzullo

69

Gần đây tôi đã viết một bài blog kỹ thuật trên về chính 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 cuộc đại tu trên bảng tạm của chúng tôi).

Sao chép văn bản đơn giản vào bảng tạm tương đối đơn giản, giả sử bạn muốn thực hiện trong sự kiện sao chép hệ thống (người dùng nhấn CtrlChoặc sử dụng menu 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();
});

Đưa văn bản vào clipboard không phải trong một sự kiện sao chép hệ thống 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 để làm điều đó thông qua Flash, đây là cách duy nhất trên trình duyệt chéo để thực hiện (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 thông qua:

window.clipboardData

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

Trong Chrome, bạn có thể tạo tiện ích mở rộng Chrome sẽ cung cấp cho bạn quyền truy cậ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 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 một số trang web nhất định để truy cập vào bảng tạm, nhưng tôi chưa từng thử bất kỳ trang nào trong số này.


2
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 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 quyền điều khiển các sự kiện sao chép bình thường khác.
Brock Adams

Lưu ý! Trình duyệt này đánh hơi là BAD. Làm tính năng đánh hơi. Bạn đang làm cho IE khó cập nhật.
odinho - Velmont

51

clipboard.js là một tiện ích nhỏ, không phải Flash, cho phép sao chép dữ liệu văn bản hoặc HTML vào bảng tạm. Nó rất dễ sử dụng, chỉ cần bao gồm .js và sử dụng 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 có trên GitHub .

Lưu ý: Điều này đã bị phản đối ngay bây giờ. Di chuyển đến đây .


Thư viện này được angular.io sử dụng cho Tour of Hero và dự phòng ở 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

1
Có vẻ như clipboard.js đã được thay thế hoặc rẽ nhánh, nhưng dường như nó vẫn tồn tại và được duy trì tích cực tại npmjs.com/package/clipboard
Joao

35

ZeroClipboard là giải pháp đa trình duyệt 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 flash cho iOS, bạn chỉ cần thêm dự phòng:

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


25
trình duyệt chéo với Flash? không hoạt động trong iOS và Android 4.4
Raptor

1
Xem câu trả lời cập nhật. Điều này cho phép ít bước hơn cho người dùng flash và dự phòng cho những người khác.
Justin

8
Nó có một tỷ dòng mã. nó hoàn toàn lố bịch. tốt hơn hết là đừng 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

2
Có một phiên bản đơn giản gist.github.com/JamesMGreene/8698897 là 20K không có tất cả chuông và còi trong phiên bản 74k. Không phải là rất lớn. Tôi đoán là hầu hết người dùng đều ổn với một phần nghìn giây mà một tệp 74k hoặc 20k được tải xuống sẽ mất để sao chép / dán là một lần nhấp thay vì hai lần.
Justin

@Justin Tôi chỉ 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 srccác thẻ script). Tôi cảm thấy rằng tài liệu của họ là đẹp nhưng không hiệu quả.
Gui Imamura

29

Năm 2018, đây là cách bạn có thể thực hiện:

async copySomething(text?) {
  try {
    const toCopy = text || location.href;
    await navigator.clipboard.writeText(toCopy);
    console.log('Text or Page URL copied');
  }
  catch (err) {
    console.error('Failed to copy: ', err);
  }
}

Nó được sử dụng trong mã Angular 6+ của tôi như vậy:

<button mat-menu-item (click)="copySomething()">
    <span>Copy link</span>
</button>

Nếu tôi vượt qua trong một chuỗi, nó sao chép nó. Nếu không có gì, nó sao chép URL của trang.

Nhiều môn thể dục hơn cho các công cụ clipboard có thể được thực hiện quá. Xem thêm thông tin tại đây:

Bỏ chặn truy cập Clipboard


bạn đã liên kết với localhost
Joe Warner

2
Xin lưu ý rằng điều này không hoạt động trong Safari (phiên bản 11.1.2)
arjun27

1
@ arjun27 Vâng hy vọng một ngày nào đó Apple sẽ bắt kịp. Mặc dù caniuse.com/#feat=clipboard này hiển thị phiên bản trên mà bạn đã đề cập để được hỗ trợ một phần.
KhoPhi

2
Tôi đang nhận được cả hai chức năng readText, hãy viết một lời hứa trong trạng thái bị từ chối
ramin

3
Theo liên kết được cung cấp, "navigator.clipboard chỉ được hỗ trợ cho các trang được phục vụ qua HTTPS"
TimH - Codidact

26

Từ một trong những dự án tôi đang thực hiện, một plugin sao chép vào bảng tạm của jQuery sử dụng Zero Clipboard thư viện .

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


6
92kb thực sự không lớn lắm, nó hoạt động rất nhanh và bạn có thể sử dụng text()thay vì innerHTML()nếu bạn thích ..
RozzA

17
@ John: innerHTMLđã được hỗ trợ nhiều trình duyệt từ lâu. Chỉ vì Microsoft ban đầu đưa ra ý tưởng mà nó không làm cho nó không đáng tin cậy hoặc độc quyền. Bây giờ nó cuối cùng 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 lớn đã thêm hỗ trợ cho nó ... thở dài ).
James M. Greene

19
@ John Bạn phàn nàn về việc jQuery không đủ JavaScripty trong câu trả lời sử dụng Flash;)
Max Nanasy

4
InternalHTML tốt hơn so với các lựa chọn thay thế trong hầu hết các trường hợp. Xuống ngựa cao đi! Nó nhanh hơn, hiệu quả hơn và không yêu cầu kết xuất lại trang.
Quỹ đạo Eden

4
@RozzA 92KBthực sự lớn. Cho đến khi LTE đáo hạn GPRSchuẩn dữ liệu di động WW và bắt đầu từ 1 KB/s. Tự mình làm toán.
Tino

23

Vì Chrome 42+ và Firefox 41+ hiện hỗ trợ lệnh document.execCommand ('copy') . Vì vậy, tôi đã tạo ra một số chức năng cho khả năng sao chép vào trình duyệt chéo trên trình duyệt bằng cách sử dụng kết hợp câu trả lời cũ của Tim Downcâu trả lời của Google Developer :

function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // IE
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
        textRange.execCommand("Copy");
    } 
    else if (window.getSelection && document.createRange) {
        // Non-Internet Explorer
        var range = document.createRange();
        range.selectNodeContents(el);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copy command was ' + msg);
        }
        catch (err) {
            console.log('Oops, unable to copy');
        }
    }
} // end function selectElementContents(el)

function make_copy_button(el) {
    var copy_btn = document.createElement('input');
    copy_btn.type = "button";
    el.parentNode.insertBefore(copy_btn, el.nextSibling);
    copy_btn.onclick = function() {
        selectElementContents(el);
    };

    if (document.queryCommandSupported("copy") || parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 42) {
        // Copy works with Internet Explorer 4+, Chrome 42+, Firefox 41+, Opera 29+
        copy_btn.value = "Copy to Clipboard";
    }
    else {
        // Select only for Safari and older Chrome, Firefox and Opera
        copy_btn.value = "Select All (then press Ctrl + C to Copy)";
    }
}
/* Note: document.queryCommandSupported("copy") should return "true" on browsers that support copy
    but there was a bug in Chrome versions 42 to 47 that makes it return "false".  So in those
    versions of Chrome feature detection does not work!
    See https://code.google.com/p/chromium/issues/detail?id=476508
*/

make_copy_button(document.getElementById("markup"));
<pre id="markup">
  Text that can be copied or selected with cross browser support.
</pre>


Cảm ơn vì đã tóm tắt điều này! Bạn có một chút sai lầm trong mã của mình: bạn đã xác định biến "phạm vi" hai lần (var Range = document.createRange ()).
Christian Engel

1
Bạn đúng @ChristianEngel. Tôi đã loại bỏ cái thứ hai. Tôi không biết làm thế nào nó có trong đó.
Jeff Baker

23

Tôi sử dụng nó rất thành công ( không có jQuery hoặc bất kỳ khung công tác nào khác).

function copyToClp(txt){
    txt = document.createTextNode(txt);
    var m = document;
    var w = window;
    var b = m.body;
    b.appendChild(txt);
    if (b.createTextRange) {
        var d = b.createTextRange();
        d.moveToElementText(txt);
        d.select();
        m.execCommand('copy');
    } 
    else {
        var d = m.createRange();
        var g = w.getSelection;
        d.selectNodeContents(txt);
        g().removeAllRanges();
        g().addRange(d);
        m.execCommand('copy');
        g().removeAllRanges();
    }
    txt.remove();
}

Cảnh báo

Các tab được chuyển đổi thành dấu cách (ít nhất là trong Chrome).


Không gian bị thiếu trong cách tiếp cận này
Bikram

1
Trình duyệt Chrome. các tab được chuyển đổi thành một không gian
Bikram

22

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

Trên trình xử lý xuống phím 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à bản sao văn bản đã chọn.

Và nếu bạn cần, bạn có thể được đặt thời gian chờ cho chức năng để khôi phục lựa chọn trước đó. Triển khai của tôi về 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 textarea 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 giải pháp trình duyệt chéo hoàn toàn mà không cần flash. Nó hoạt động trong FF và Chrome.


2
Có ai đã thử nó chưa? Nghe có vẻ 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

1
jsfiddle.net/H2FHC Demo: 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 cũng vậy. Opera 12,14 - OK. Safari 5.1.7 cho Windows - OK. IE - FAIL.
Enyby

Đối với IE cần chạy tập trung vào phần tử bên trong trang. Xem fiddle.jshell.net/H2FHC/3/showfiddle.jshell.net/H2FHC/3 Đã làm việc trong IE 9/10. IE 6/7 cần quá trình tạo lựa chọn theo cách khác vì document.createRange không được hỗ trợ.
Enyby

21

Các phương pháp khác sẽ sao chép văn bản đơn giản vào bảng tạm. Để sao chép HTML (nghĩa là bạn có thể dán kết quả vào trình soạn thảo WSIWYG), bạn chỉ có thể thực hiện các thao tác sau trong IE . Điều này về cơ bản là khác với các phương pháp khác, vì trình duyệt thực sự chọn nội dung rõ ràng.

// create an editable DIV and append the HTML content you want copied
var editableDiv = document.createElement("div");
with (editableDiv) {
    contentEditable = true;
}     
editableDiv.appendChild(someContentElement);          

// select the editable content and copy it to the clipboard
var r = document.body.createTextRange();
r.moveToElementText(editableDiv);
r.select();  
r.execCommand("Copy");

// deselect, so the browser doesn't leave the element visibly selected
r.moveToElementText(someHiddenDiv);
r.select();   

xem thêm giải pháp HTML đầy đủ tại đây stackoverflow.com/questions
432191780 / Từ

21

Tôi đã tập hợp những gì tôi nghĩ là tốt nhất.

  • Sử dụng cssText để tránh các ngoại lệ trong Internet Explorer trái ngược với kiểu trực tiếp.
  • Khôi phục lựa chọn nếu có
  • Đặt chỉ đọc để bàn phím không xuất hiện trên thiết bị di động
  • Có một cách giải quyết cho iOS để nó thực sự hoạt động như bình thường khi chặn execCommand.

Đây là:

const copyToClipboard = (function initClipboardText() {
  const textarea = document.createElement('textarea');

  // Move it off screen.
  textarea.style.cssText = 'position: absolute; left: -99999em';

  // Set to readonly to prevent mobile devices opening a keyboard when
  // text is .select()'ed.
  textarea.setAttribute('readonly', true);

  document.body.appendChild(textarea);

  return function setClipboardText(text) {
    textarea.value = text;

    // Check if there is any content selected previously.
    const selected = document.getSelection().rangeCount > 0 ?
      document.getSelection().getRangeAt(0) : false;

    // iOS Safari blocks programmtic execCommand copying normally, without this hack.
    // /programming/34045777/copy-to-clipboard-using-javascript-in-ios
    if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
      const editable = textarea.contentEditable;
      textarea.contentEditable = true;
      const range = document.createRange();
      range.selectNodeContents(textarea);
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
      textarea.setSelectionRange(0, 999999);
      textarea.contentEditable = editable;
    }
    else {
      textarea.select();
    }

    try {
      const result = document.execCommand('copy');

      // Restore previous selection.
      if (selected) {
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(selected);
      }

      return result;
    }
    catch (err) {
      console.error(err);
      return false;
    }
  };
})();

Sử dụng: copyToClipboard('some text')


13

Kể từ Flash 10, bạn chỉ có thể sao chép vào khay nhớ tạm nếu hành động bắt nguồn từ tương tác của người dùng với đối tượng Flash. ( Đọc phần liên quan từ thông báo Flash 10 của Adobe )

Giải pháp là để quá mức một đối tượng flash phía trên nút Copy hoặc bất kỳ yếu tố nào khởi tạo bản sao. Zero Clipboard hiện là thư viện tốt nhất với việc thực hiện này. Các nhà phát triển Flash có kinh nghiệm có thể chỉ muốn tạo thư viện của riêng họ.


12

  <!DOCTYPE html>

  <style>
    #t {
      width: 1px
      height: 1px
      border: none
    }
    #t:focus {
      outline: none
    }
  </style>

  <script>
    function copy(text) {
      var t = document.getElementById('t')
      t.innerHTML = text
      t.select()
      try {
        var successful = document.execCommand('copy')
        var msg = successful ? 'successfully' : 'unsuccessfully'
        console.log('text coppied ' + msg)
      } catch (err) {
        console.log('Unable to copy text')
      }
      t.innerHTML = ''
    }
  </script>

  <textarea id=t></textarea>

  <button onclick="copy('hello world')">
    Click me
  </button>


Câu trả lời tốt nhất: D, bạn có thể cải thiện nó bằng một cái gì đó như thế này: #t {vị trí: tuyệt đối; trái: 0; chỉ số z: -900; chiều rộng: 0px; chiều cao: 0px; biên giới: không có; } Vì vậy, nó sẽ được ẩn hoàn toàn! Nhưng thực sự cảm ơn người anh em!
Federico Navarittle

#t {thay đổi kích thước: không có;}
SmartManoj

Một lời giải thích sẽ theo thứ tự.
Peter Mortensen

12

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

Tôi có văn bản trong một đầu vào ẩn. Vì setSelectionRangekhông hoạt động trên các đầu vào ẩn, tôi tạm thời thay đổi loại thành văn bản, sao chép văn bản và sau đó làm cho nó bị ẩn đi. Nếu bạn muốn sao chép văn bản từ một phần tử, bạn có thể chuyển nó vào hàm và lưu nội dung của nó trong biến mục tiêu.

jQuery('#copy').on('click', function () {
    copyToClipboard();
});

function copyToClipboard() {
    var target = jQuery('#hidden_text');

    // Make it visible, so can be focused
    target.attr('type', 'text');
    target.focus();
    // Select all the text
    target[0].setSelectionRange(0, target.val().length);

    // Copy the selection
    var succeed;
    try {
        succeed = document.execCommand("copy");
    }
    catch (e) {
        succeed = false;
    }

    // Hide input again
    target.attr('type', 'hidden');

    return succeed;
}

11

Sao chép văn bản từ đầu vào HTML vào bảng tạm:

 function myFunction() {
   /* Get the text field */
   var copyText = document.getElementById("myInput");

   /* Select the text field */
   copyText.select();

   /* Copy the text inside the text field */
   document.execCommand("Copy");

   /* Alert the copied text */
   alert("Copied the text: " + copyText.value);
 }
 <!-- The text field -->
 <input type="text" value="Hello Friend" id="myInput">

 <!-- The button used to copy the text -->
<button onclick="myFunction()">Copy text</button>

Lưu ý: Các document.execCommand()phương pháp không được hỗ trợ trong Internet Explorer 9 và trước đó.

Nguồn : W3Schools - Sao chép văn bản vào Clipboard


11

Đã có nhiều câu trả lời, tuy nhiên muốn thêm một (jQuery). Hoạt động tốt trên bất kỳ trình duyệt nào, cả trình duyệt di động (nghĩa là nhắc nhở về bảo mật, nhưng khi bạn chấp nhận thì nó chỉ hoạt động tốt).

function appCopyToClipBoard(sText)
{
    var oText = false,
        bResult = false;
    try
    {
        oText = document.createElement("textarea");
        $(oText).addClass('clipboardCopier').val(sText).insertAfter('body').focus();
        oText.select();
        document.execCommand("Copy");
        bResult = true;
    }
    catch(e) {
    }

    $(oText).remove();
    return bResult;
}

Trong mã của bạn:

if (!appCopyToClipBoard('Hai there! This is copied to the clipboard.'))
{
    alert('Sorry, copy to clipboard failed.');
}

9

Đây là một chút kết hợp giữa các câu trả lời khác.

var copyToClipboard = function(textToCopy){
    $("body")
        .append($('<textarea name="fname" class="textToCopyInput"/>' )
        .val(textToCopy))
        .find(".textToCopyInput")
        .select();
      try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        alert('Text copied to clipboard!');
      } catch (err) {
          window.prompt("To copy the text to clipboard: Ctrl+C, Enter", textToCopy);
      }
     $(".textToCopyInput").remove();
}

Nó sử dụng jQuery, nhưng tất nhiên nó không phải. Bạn có thể thay đổi điều đó nếu bạn muốn. Tôi vừa có jQuery để xử lý. Bạn cũng có thể thêm một số CSS để đảm bảo đầu vào không hiển thị. Ví dụ:

.textToCopyInput{opacity: 0; position: absolute;}

Hoặc tất nhiên bạn cũng có thể làm một số phong cách nội tuyến

.append($('<textarea name="fname" style="opacity: 0;  position: absolute;" class="textToCopyInput"/>' )

Cách sao chép trực tiếp từ dữ liệu biến .ie: var str = "word"; ?

Thông điệp biến không được sử dụng
Voyager

Tốt hơn nên sử dụng '<textarea class = "textToCopyInput" /> </ textarea>' trong trường hợp textToCopycó chứa\n
Voyager

8

Trong các trình duyệt không phải IE, bạn cần sử dụng một đối tượng flash nhỏ để thao tác với bảng tạm, ví dụ:


Điều này đã lỗi thời ngay bây giờ ... hãy xem đề xuất của GvS
Mottie

6
GvS gợi ý sử dụng phim flash? Đó không phải là cùng một ý tưởng sao?
TheEmirOfGroofunkistan

8

Tôi gặp vấn đề tương tự khi xây dựng một chỉnh sửa lưới tùy chỉnh từ (một cái gì đó như Excel) và khả năng tương thích với Excel. Tôi đã phải hỗ trợ chọn nhiều ô, sao chép và dán.

Giải pháp: tạo một vùng văn bản nơi bạn sẽ chèn dữ liệu để người dùng sao chép (đối với tôi khi người dùng đang chọn ô), hãy đặt tiêu điểm vào đó (ví dụ: khi người dùng nhấn Ctrl ) và chọn toàn bộ văn bản.

Vì vậy, khi người dùng nhấn Ctrl+ Canh ấy / cô ấy được sao chép các ô anh ấy / cô ấy đã chọn. Sau khi kiểm tra, chỉ thay đổi kích thước vùng văn bản thành một pixel (Tôi không kiểm tra xem nó có hoạt động trên màn hình không: không). Nó hoạt động độc đáo trên tất cả các trình duyệt và nó minh bạch cho người dùng.

Dán - bạn có thể làm tương tự như thế này (khác với mục tiêu của bạn) - tiếp tục tập trung vào textarea và bắt các sự kiện dán bằng cách sử dụng onpaste (trong dự án của tôi, tôi sử dụng textareas trong các ô để chỉnh sửa).

Tôi không thể dán một ví dụ (dự án thương mại), nhưng bạn có ý tưởng.


7

Tôi đã sử dụng clipboard.js.

Chúng tôi có thể lấy nó vào npm:

npm install clipboard --save

Và cũng trên Bower

bower install clipboard --save

Cách sử dụng & ví dụ có tại https://zenorocha.github.io/clipboard.js/ .


Tôi sợ rằng nó không tương thích với nội dung động, nhưng nó là ;-) Tôi nghĩ rằng đó là giải pháp tốt hơn, NGAY BÂY GIỜ, so với giải pháp cũ của năm 2008
BẾN Patrick


6

Đây là bản mở rộng câu trả lời của @ Chase, với ưu điểm là nó sẽ hoạt động cho các yếu tố IMAGE và TABLE, không chỉ DIV trên IE9.

if (document.createRange) {
    // IE9 and modern browsers
    var r = document.createRange();
    r.setStartBefore(to_copy);
    r.setEndAfter(to_copy);
    r.selectNode(to_copy);
    var sel = window.getSelection();
    sel.addRange(r);
    document.execCommand('Copy');  // does nothing on FF
} else {
    // IE 8 and earlier.  This stuff won't work on IE9.
    // (unless forced into a backward compatibility mode,
    // or selecting plain divs, not img or table). 
    var r = document.body.createTextRange();
    r.moveToElementText(to_copy);
    r.select()
    r.execCommand('Copy');
}

5

Có vẻ như tôi đã đọc sai câu hỏi, nhưng để tham khảo, bạn có thể trích xuất một phạm vi DOM (không vào bảng tạm; tương thích với tất cả các trình duyệt hiện đại) và kết hợp nó với các sự kiện oncopy và onpaste và onb Beforepaste để có hành vi clipboard. Đây là mã để đạt được điều này:

function clipBoard(sCommand) {
  var oRange=contentDocument.createRange();
  oRange.setStart(startNode, startOffset);
  oRange.setEnd(endNode, endOffset);
/* This is where the actual selection happens.
in the above, startNode and endNode are dom nodes defining the beginning 
and end of the "selection" respectively. startOffset and endOffset are 
constants that are defined as follows:

END_TO_END: 2
END_TO_START: 3
NODE_AFTER: 1
NODE_BEFORE: 0
NODE_BEFORE_AND_AFTER: 2
NODE_INSIDE: 3
START_TO_END: 1
START_TO_START: 0

and would be used like oRange.START_TO_END */
      switch(sCommand) {
    case "cut":
          this.oFragment=oRange.extractContents();
      oRange.collapse();
      break;
    case "copy":
      this.oFragment=oRange.cloneContents();
      break;
    case "paste":
      oRange.deleteContents();
      var cloneFragment=this.oFragment.cloneNode(true)
      oRange.insertNode(cloneFragment);
      oRange.collapse();
      break;
  }
}

1
Thật ra tôi đã sửa mã. Nó hoạt động trong tất cả các trình duyệt nhưng không thực sự sao chép vào clipboard. Chỉ cần trích xuất (cắt), nhân bản (bản sao) nội dung thông qua các biến. Có vẻ như tôi đã quên việc sử dụng.
mrBorna

5

Lỗi của tôi. Điều này chỉ hoạt động trong IE.

Đây là một cách khác để sao chép văn bản:

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>

9
Điều này không hoạt động trong Chrome hiện tại (V31) hoặc FireFox (v25). Lỗi là window.clipboardData không xác định. Về mặt tích cực, nó hoạt động trong IE9. Vì vậy, miễn là bạn không quan tâm đến các trình duyệt tốt và muốn khóa trang web của bạn bằng cách sử dụng các trình duyệt xấu, đây là cách để bạn làm điều đó!
Anthony

2
tôi không hiểu tại sao rất nhiều câu trả lời ngớ ngẩn. w3schools.com/howto/tryit.asp?filename=tryhow_js_copy_clipboard
Martian2049

5

Đây là điều duy nhất tôi từng làm việc, sau khi tìm kiếm nhiều cách khác nhau trên Internet. Đây là một chủ đề lộn xộn. Có rất nhiều giải pháp được đăng tải trên khắp thế giới và hầu hết chúng không hoạt động. Điều này làm việc cho tôi:

LƯU Ý: Mã này sẽ chỉ hoạt động khi được thực thi dưới dạng mã đồng bộ trực tiếp với một cái gì đó giống như phương thức 'onClick'. Nếu bạn gọi một phản hồi không đồng bộ với Ajax hoặc theo bất kỳ cách không đồng bộ nào khác, nó sẽ không hoạt động.

copyToClipboard(text) {
    var copyText = document.createElement("input");
    copyText.type = "text";
    document.body.appendChild(copyText);
    copyText.style = "display: inline; width: 1px;";
    copyText.value = text;
    copyText.focus();
    document.execCommand("SelectAll");
    document.execCommand("Copy");
    copyText.remove();
}

Tôi thực sự nhận ra mã này sẽ hiển thị một thành phần rộng 1 pixel trên màn hình trong một phần nghìn giây, nhưng quyết định không lo lắng về điều đó, đây là điều mà người khác có thể giải quyết nếu có vấn đề thực sự.


5

Để sao chép văn bản đã chọn ('Text To Copy') vào khay nhớ tạm của bạn, hãy tạo Bookmarklet (dấu trang trình duyệt thực thi JavaScript) và thực thi nó (nhấp vào nó). Nó sẽ tạo ra một textarea tạm thời.

Mã từ GitHub:

https://gist.github.com/stefanmaric/2abf96c740191cda3bc7a8b0fc905a7d

(function (text) {
  var node = document.createElement('textarea');
  var selection = document.getSelection();

  node.textContent = text;
  document.body.appendChild(node);

  selection.removeAllRanges();
  node.select();
  document.execCommand('copy');

  selection.removeAllRanges();
  document.body.removeChild(node);
})('Text To Copy');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.