Tổng quat
Có ba API trình duyệt chính để sao chép vào bảng tạm:
- 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.
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.
- 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 và "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 textarea
hoặc input
phầ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ề true
nếu lệnh "được trình duyệt hỗ trợ".
- và
document.queryCommandEnabled('copy')
trở lại 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 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 true
từ 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.queryCommandSupported
hoặc document.queryCommandEnabled
nên được gói 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 đư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.