Gambaran
Ada tiga API peramban utama untuk disalin ke clipboard:
- API Clipboard Async
[navigator.clipboard.writeText]
- Porsi yang berfokus pada teks tersedia di Chrome 66 (Maret 2018)
- Akses asinkron dan menggunakan Janji JavaScript , dapat ditulis sehingga pengguna keamanan meminta (jika ditampilkan) tidak mengganggu JavaScript di halaman.
- Teks dapat disalin ke clipboard langsung dari variabel.
- Hanya didukung pada halaman yang dilayani melalui HTTPS.
- Di Chrome 66 halaman di tab aktif dapat menulis ke clipboard tanpa izin izin.
document.execCommand('copy')
- Sebagian besar browser mendukung ini pada ~ April 2015 (lihat Dukungan Browser di bawah).
- Akses sinkron, yaitu menghentikan JavaScript di halaman hingga selesai termasuk menampilkan dan berinteraksi dengan pengguna dengan prompt keamanan.
- Teks dibaca dari DOM dan ditempatkan di clipboard.
- Selama pengujian ~ April 2015 hanya Internet Explorer yang tercatat sebagai menampilkan izin meminta saat menulis ke clipboard.
- Mengganti acara salin
- Lihat dokumentasi Clipboard API tentang Mengesampingkan acara salin .
- Memungkinkan Anda untuk mengubah apa yang muncul di clipboard dari setiap peristiwa penyalinan, dapat menyertakan format data lain selain teks biasa.
- Tidak dibahas di sini karena tidak langsung menjawab pertanyaan.
Catatan pengembangan umum
Jangan berharap perintah terkait clipboard berfungsi saat Anda menguji kode di konsol. Secara umum halaman tersebut harus aktif (Async Clipboard API) atau memerlukan interaksi pengguna (misalnya klik pengguna) untuk mengizinkan ( document.execCommand('copy')
) mengakses clipboard lihat di bawah untuk lebih jelasnya.
PENTING (dicatat di sini 2020/02/20)
Perhatikan bahwa sejak posting ini pada awalnya ditulis, penghentian izin di lintas asal IFRAME dan IFRAME "sandboxing" IFRAME lainnya mencegah demo tertanam tombol "Jalankan cuplikan kode" tombol dan "contoh codepen.io" dari bekerja di beberapa browser (termasuk Chrome dan Microsoft Edge ).
Untuk mengembangkan membuat halaman web Anda sendiri, sajikan halaman itu melalui koneksi HTTPS untuk diuji dan dikembangkan.
Berikut ini adalah halaman uji / demo yang menunjukkan kode berfungsi:
https://deanmarktaylor.github.io/clipboard-test/
Async + Fallback
Karena tingkat dukungan browser untuk Async Clipboard API baru, Anda mungkin ingin mundur ke document.execCommand('copy')
metode untuk mendapatkan jangkauan browser yang baik.
Berikut ini adalah contoh sederhana (mungkin tidak berfungsi tertanam di situs ini, baca catatan "penting" di atas):
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>
(contoh codepen.io mungkin tidak berfungsi, baca catatan "penting" di atas) Perhatikan bahwa cuplikan ini tidak berfungsi dengan baik di pratinjau tertanam Stack Overflow, Anda dapat mencobanya di sini: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors = 1011
API Clipboard Async
Perhatikan bahwa ada kemampuan untuk "meminta izin" dan menguji akses ke clipboard melalui API izin di 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')
Sisa dari pos ini membahas nuansa dan detail document.execCommand('copy')
API.
Dukungan Browser
document.execCommand('copy')
Dukungan JavaScript telah berkembang, lihat tautan di bawah untuk pembaruan browser:
Contoh sederhana
(mungkin tidak berfungsi tertanam di situs ini, baca catatan "penting" di atas)
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>
Contoh Kompleks: Salin ke clipboard tanpa menampilkan input
Contoh sederhana di atas berfungsi dengan baik jika ada elemen textarea
atau input
yang terlihat di layar.
Dalam beberapa kasus, Anda mungkin ingin menyalin teks ke clipboard tanpa menampilkan input
/ textarea
elemen. Ini adalah salah satu contoh cara untuk mengatasi ini (pada dasarnya memasukkan elemen, salin ke clipboard, hapus elemen):
Diuji dengan Google Chrome 44, Firefox 42.0a1 dan Internet Explorer 11.0.8600.17814.
(mungkin tidak berfungsi tertanam di situs ini, baca catatan "penting" di atas)
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>
Catatan tambahan
Hanya berfungsi jika pengguna mengambil tindakan
Semua document.execCommand('copy')
panggilan harus dilakukan sebagai akibat langsung dari tindakan pengguna, mis. Klik pengendali acara. Ini adalah langkah untuk mencegah mengacaukan clipboard pengguna ketika mereka tidak mengharapkannya.
Lihat posting Google Developers di sini untuk info lebih lanjut.
API Clipboard
Perhatikan spesifikasi draft API Clipboard lengkap dapat ditemukan di sini:
https://w3c.github.io/clipboard-apis/
Apakah ini didukung?
document.queryCommandSupported('copy')
harus kembali true
jika perintah "didukung oleh browser".
- dan
document.queryCommandEnabled('copy')
kembali true
jika document.execCommand('copy')
akan berhasil jika dipanggil sekarang. Memeriksa untuk memastikan perintah dipanggil dari utas yang dimulai pengguna dan persyaratan lainnya dipenuhi.
Namun sebagai contoh masalah kompatibilitas browser, Google Chrome dari ~ April hingga ~ Oktober 2015 hanya kembali true
dari document.queryCommandSupported('copy')
jika perintah dipanggil dari utas yang dimulai pengguna.
Perhatikan detail kompatibilitas di bawah ini.
Detail Kompatibilitas Browser
Sementara panggilan sederhana untuk document.execCommand('copy')
dibungkus dengan try
/ catch
blok yang disebut sebagai hasil dari klik pengguna akan membuat Anda mendapatkan kompatibilitas yang paling banyak, yang berikut memiliki beberapa ketentuan:
Setiap panggilan ke document.execCommand
, document.queryCommandSupported
atau document.queryCommandEnabled
harus dibungkus dengan try
/ catch
blok.
Implementasi browser yang berbeda dan versi browser melempar berbagai jenis pengecualian ketika dipanggil alih-alih kembali false
.
Implementasi browser yang berbeda masih dalam fluks dan Clipboard API masih dalam konsep, jadi ingatlah untuk melakukan pengujian Anda.