Bagaimana cara menyalin ke clipboard di JavaScript?

3322

Apa cara terbaik untuk menyalin teks ke clipboard? (multi-browser)

Saya telah mencoba:

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

tetapi di Internet Explorer itu memberikan kesalahan sintaksis. Di Firefox, katanya unsafeWindow is not defined.

Trik yang bagus tanpa flash: Bagaimana Trello mengakses clipboard pengguna?

Santiago Corredoira
sumber
Hanya ingin tahu, apa yang ingin Anda salin ke clipboard yang tidak dapat dilakukan sendiri oleh pengguna?
scunliffe
233
Tidak ada yang spesial. Mereka dapat melakukannya sendiri tetapi saya ingin menawarkan juga kemungkinan mengklik tombol tanpa khawatir memilih bagian teks yang benar.
Santiago Corredoira
4
Posting blog yang panjang ini berisi banyak cara untuk melakukan ini: Mengakses Sistem Clipboard dengan JavaScript - A Holy Grail?
Aaron Digulla
Ini memberikan pengecualian yang tidak ditentukan browser di IE serta di FF
Jagadeesh
1
Jika kita dapat memasukkan teks ke clipboard pengguna, kita dapat merusak clipboardnya.
Frank Fang

Jawaban:

2249

Gambaran

Ada tiga API peramban utama untuk disalin ke clipboard:

  1. 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.
  2. 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.
  3. 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 textareaatau inputyang terlihat di layar.

Dalam beberapa kasus, Anda mungkin ingin menyalin teks ke clipboard tanpa menampilkan input/ textareaelemen. 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 truejika perintah "didukung oleh browser".
  • dan document.queryCommandEnabled('copy')kembali truejika 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 truedari 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/ catchblok 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.queryCommandSupportedatau document.queryCommandEnabledharus dibungkus dengan try/ catchblok.

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.

Dean Taylor
sumber
41
cara menyalin langsung dari Yaitu data variabel: var str = "word";?
jscripter
10
@BubuDaba Buat dummy yang disembunyikan <textarea>dengan JS, tambahkan ke document.body, atur nilainya ke variabel, dan gunakan sesuai langkah copyTextarea, kemudian hapus segera setelah konten disalin.
SeinopSys
3
Apakah ada sesuatu untuk Safari atau indikator apa pun yang akan diterapkan di Safari?
www139
3
Satu-satunya versi yang saya temukan yang berfungsi di semua browser. Saya menemukan ketika menggunakan ini di Boostrap Modal saya harus menambahkan area teks ke modal. Saya akan memberikan +1000 jika saya bisa untuk solusi Anda !!! TERIMA KASIH!
Patrick
3
@AyaSalama titik kuncinya adalah bahwa tindakan "salin" tidak dapat terjadi kecuali jika muncul ke browser pengguna mengambil tindakan. Pengguna tidak akan dapat mengambil tindakan jika elemennya ditata dengan "display: none" karena mereka tidak akan dapat melihatnya, atau berinteraksi dengannya.
Dean Taylor
1257

Menyalin otomatis ke clipboard mungkin berbahaya, oleh karena itu sebagian besar browser (kecuali IE) membuatnya sangat sulit. Secara pribadi, saya menggunakan trik sederhana berikut:

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

Pengguna disajikan dengan kotak prompt, di mana teks yang akan disalin sudah dipilih. Sekarang cukup untuk menekan Ctrl+ Cdan Enter(untuk menutup kotak) - dan voila!

Sekarang operasi penyalinan clipboard adalah AMAN, karena pengguna melakukannya secara manual (tetapi dengan cara yang sangat mudah). Tentu saja, berfungsi di semua browser.

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

Jarek Milewski
sumber
91
Pintar, tetapi ini hanya mendukung satu baris.
Aram Kocharyan
61
Ini sepele untuk mengubah fungsi "prompt" menjadi modal khusus, inti dari masalahnya adalah menggunakan bidang konten yang dapat diedit dan memilih teks sebelumnya, dan tidak merusak UI browser dengan memberlakukan bahwa pengguna mengambil bertindak sendiri. A ++
Jon z
110
masih tidak menggunakan javascript untuk menyalin ke clipboard ^ _ ^
RozzA
23
Jika teks Anda lebih dari 2000 karakter, maka akan dipotong, tetapi untuk sampel teks yang lebih kecil itu berfungsi dengan baik
RasTheDestroyer
445
Aneh bahwa ini mendapat 457 upvotes sementara itu tidak menjawab pertanyaan: salin ke clipboard di Javascript !
stevenvh
300

Pendekatan berikut berfungsi di Chrome, Firefox, Internet Explorer dan Edge, dan dalam versi terbaru Safari (dukungan salin ditambahkan dalam versi 10 yang dirilis Oktober 2016).

  • Buat textarea dan atur isinya ke teks yang ingin Anda salin ke clipboard.
  • Tambahkan teks ke DOM.
  • Pilih teks dalam textarea.
  • Hubungi document.execCommand ("copy")
  • Hapus textarea dari dom.

Catatan: Anda tidak akan melihat textarea, karena ditambahkan dan dihapus dalam permintaan kode Javascript yang sama dan sinkron.

Beberapa hal yang harus diperhatikan jika Anda menerapkan ini sendiri:

  • Untuk alasan keamanan, ini hanya dapat dipanggil dari pengendali acara seperti klik (Seperti halnya membuka jendela).
  • Internet Explorer akan menampilkan dialog izin saat pertama kali papan klip diperbarui.
  • Internet Explorer, dan Edge akan menggulir ketika textarea difokuskan.
  • execCommand () dapat melempar dalam beberapa kasus.
  • Baris baru dan tab bisa tertelan kecuali Anda menggunakan textarea. (Sebagian besar artikel tampaknya merekomendasikan penggunaan div)
  • Textarea akan terlihat ketika dialog Internet Explorer ditampilkan, Anda harus menyembunyikannya, atau menggunakan clipboardData API khusus Internet Explorer.
  • Di Internet Explorer, administrator sistem dapat menonaktifkan API clipboard.

Fungsi di bawah ini harus menangani semua masalah berikut sebersih mungkin. Silakan tinggalkan komentar jika Anda menemukan masalah atau punya saran untuk memperbaikinya.

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

Greg Lowe
sumber
9
Jawaban yang bagus: dukungan lintas browser, penanganan kesalahan + pembersihan. Pada dukungan baru hari ini untuk queryCommandSupported, menyalin ke clipboard sekarang layak di Javascript dan ini harus menjadi jawaban yang diterima, bukan canggung 'window.prompt ("Salin ke clipboard: Ctrl + C, Enter", teks)' solusi. window.clipboardData didukung di IE9, jadi Anda harus menambahkan IE9 dalam daftar dukungan browser dan saya pikir mungkin IE8 dan sebelumnya juga, tetapi perlu memverifikasi.
user627283
Ya. IE 8/9 Harusnya ok. Aplikasi kami tidak mendukung mereka. Jadi saya belum menguji. IE menghentikan dukungan di Jan, jadi saya tidak terlalu sibuk. Semoga dukungan Safari akan segera mendarat. Saya yakin itu ada di radar mereka.
Greg Lowe
4
@SantiagoCorredoira: Pada tahun 2016, ini layak menjadi jawaban yang diterima. Silakan pertimbangkan untuk menetapkan kembali BGT (centang hijau besar).
Lawrence Dol
3
@Noitidart I Diuji dan berfungsi dengan baik untuk firefox 54, chrome 60 dan browser tepi, bahkan ketika fokus tidak ada dalam dokumen html, kesalahan yang Anda alami mungkin spesifik untuk versi FF 55
Tosin John
2
@Noitidart Masih berfungsi dengan baik di sini, fokus pada alat dev tidak menghentikannya. Omong-omong, apa yang akan dilakukan pengguna aplikasi web pada perangkat pengembang
Tosin John
97

Ini pendapat saya tentang yang itu ...

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: Perhatikan bahwa menggunakan inputbidang html tidak akan menghormati jeda baris \ndan akan meratakan teks apa pun menjadi satu baris.

Seperti yang disebutkan oleh @nikksan di komentar, menggunakan textareaakan memperbaiki masalah sebagai berikut:

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
sumber
@nikksan cara menyalin string \n?
Sof-03
2
@ sof-03 gunakan textarea alih-alih input dan tambahkan \r\nuntuk jeda baris
nikksan
1
Tidak bekerja di Microsoft Edge 42.17134.1.0 di Win10x64
Honsa Stunna
3
Saya sudah menyalin jawaban Anda. Ini bekerja di chrome dan itu yang saya butuhkan.
user875234
Ini adalah solusi paling sederhana yang bekerja dengan Firefox v68.0.2 (64-bit).
Arya
88

Jika Anda menginginkan solusi yang benar-benar sederhana (membutuhkan waktu kurang dari 5 menit untuk berintegrasi) dan terlihat bagus di luar kotak, maka Clippy adalah alternatif yang bagus untuk beberapa solusi yang lebih kompleks.

Itu ditulis oleh salah satu pendiri GitHub. Contoh kode embed Flash di bawah ini:

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

Ingatlah untuk mengganti #{text}dengan teks yang perlu Anda salin, dan #{bgcolor}dengan warna.

Brent Matzelle
sumber
12
Bagi siapa pun yang tertarik, periksa Clippy yang digunakan di GitHub saat menyalin URL untuk repo.
Radek
66
FYI, penggunaan Clippy on GitHub telah digantikan oleh ZeroClipboard.
James M. Greene
219
OP menginginkan solusi dalam JavaScript. Bukan flash.
MT.
21
@ MT, oleh "javascript" beberapa orang berarti "di klien browser", jadi sementara JS-saja mungkin merupakan persyaratan, banyak orang yang berkesempatan untuk jawaban ini benar-benar mencari JS-atau-lainnya didukung secara luas- klien-tech. Flash tidak mengenai semua platform, tetapi untuk fitur semir seperti dukungan clipboard, perlu ditambahkan jika itu meningkatkan UX melalui dialog popup (yang memang benar).
Dave Dopson
13
Dengan sekarang mengandalkan Flash berarti memiliki hal-hal yang tidak berfungsi untuk persentase pengunjung situs yang tidak dapat diterima oleh hampir semua orang yang melakukan pengembangan web.
jinglesthula
86

Membaca dan memodifikasi clipboard dari halaman web menimbulkan masalah keamanan dan privasi. Namun, di Internet Explorer, dimungkinkan untuk melakukannya. Saya menemukan cuplikan contoh ini :

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

bandi
sumber
7
Menggunakan flash untuk operasi penyalinan sederhana sepertinya berlebihan, senang ada cara JS bersih untuk melakukan ini. Dan karena kita berada dalam lingkungan perusahaan. IE baik-baik saja. Bandi terima kasih!
Eddie
5
tolong jelaskan apa execCommand(\\’copy\\’);, jika tidak menyalin ke clipboard untuk IE? @mrBorna
RozzA
20
Jangan gunakan if(!document.all)tetapi if(!r.execCommand)jangan ada orang lain yang mengimplementasikannya! Document.all sama sekali tidak relevan dengan ini.
m93a
1
Sobat, inilah yang saya sukai tentang kode sederhana dan bersih, ini berfungsi hampir selamanya dengan sedikit perawatan. Ini melakukannya untuk saya, Ini bekerja dengan indah.
Samuel Ramzan
1
tidak bekerja di chrome, firefox, atau MS Edge terbaru :(
Jonathan Marzullo
69

Saya baru-baru ini menulis posting blog teknis tentang masalah ini (saya bekerja di Lucidchart dan kami baru-baru ini melakukan perombakan di clipboard kami).

Menyalin teks biasa ke clipboard relatif sederhana, dengan asumsi Anda ingin melakukannya selama acara penyalinan sistem (pengguna menekan CtrlCatau menggunakan menu browser).

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

Menempatkan teks pada clipboard bukan selama acara penyalinan sistem jauh lebih sulit. Sepertinya beberapa dari jawaban referensi cara lain untuk melakukannya melalui Flash, yang merupakan satu-satunya cara lintas-browser untuk melakukannya (sejauh yang saya mengerti).

Selain itu, ada beberapa opsi berdasarkan browser-per-browser.

Ini adalah yang paling sederhana di IE, di mana Anda dapat mengakses objek clipboard Data kapan saja dari JavaScript melalui:

window.clipboardData

(Ketika Anda mencoba melakukan ini di luar sistem memotong, menyalin, atau menempel acara, namun, IE akan meminta pengguna untuk memberikan izin clipboard aplikasi web.)

Di Chrome, Anda dapat membuat ekstensi Chrome yang akan memberi Anda izin papan klip (inilah yang kami lakukan untuk Lucidchart). Maka bagi pengguna dengan ekstensi Anda yang terpasang, Anda hanya perlu mem-flash event sistem sendiri:

document.execCommand('copy');

Sepertinya Firefox memiliki beberapa opsi yang memungkinkan pengguna untuk memberikan izin ke situs tertentu untuk mengakses clipboard, tetapi saya belum mencoba semua ini secara pribadi.

Richard Shurtz
sumber
2
Tidak disebutkan dalam posting blog (saya berharap untuk memperbaruinya dalam waktu dekat), adalah kemampuan untuk memicu cut dan copy menggunakan execCommand. Ini didukung di IE10 +, Chrome 43+, dan Opera29 +. Baca tentang ini di sini. updates.html5rocks.com/2015/04/cut-and-copy-commands
Richard Shurtz
Masalah dengan ini adalah bahwa ia membajak kegiatan penyalinan normal lainnya.
Brock Adams
NB! Sniffing browser ini BURUK. Lakukan fitur sniffing. Anda mempersulit IE untuk memperbarui.
odinho
51

clipboard.js adalah utilitas kecil, non-Flash, yang memungkinkan penyalinan data teks atau HTML ke clipboard. Ini sangat mudah digunakan, cukup sertakan .js dan gunakan sesuatu seperti ini:

<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 juga ada di GitHub .

Catatan: Ini sudah usang sekarang. Bermigrasi ke sini .

seorang programmer
sumber
Pustaka ini digunakan oleh angular.io untuk Tur Pahlawan dan mundur dalam mode anggun untuk browser yang tidak mendukung execCommand dengan menampilkan teks yang dipilih sebelumnya yang baru saja disalin oleh pengguna.
John-Philip
1
Terlihat clipboard.js telah diganti, atau bercabang, tetapi tampaknya hidup dan secara aktif dipertahankan di npmjs.com/package/clipboard
Joao
35

ZeroClipboard adalah solusi lintas-browser terbaik yang saya temukan:

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

Jika Anda memerlukan dukungan non-flash untuk iOS, Anda cukup menambahkan back-back:

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

Justin
sumber
25
lintas browser dengan Flash? tidak bekerja di iOS dan Android 4.4
Raptor
1
Lihat jawaban yang diperbarui. Ini memungkinkan lebih sedikit langkah untuk pengguna flash dan back-back untuk semua orang.
Justin
8
ia memiliki satu miliar baris kode. itu benar-benar ejekan. lebih baik tidak melakukannya sama sekali daripada memasukkan monster seperti itu dalam proyek
vsync
2
Ada versi sederhana gist.github.com/JamesMGreene/8698897 yaitu 20K yang tidak memiliki semua lonceng dan peluit dalam versi 74k. Tidak ada yang sangat besar. Dugaan saya adalah sebagian besar pengguna baik-baik saja dengan milidetik tambahan bahwa file 74k atau 20k yang sedang diunduh akan diperlukan, jadi salin / tempel adalah satu klik, bukan dua.
Justin
@Justin Saya tidak bisa membuatnya bekerja secara lokal, bahkan jika saya menyalin & menempelkan contoh (saya membuat perubahan minimum, misalnya nilai srcdalam tag skrip). Saya merasa bahwa dokumentasi mereka cukup tetapi tidak efisien.
Gui Imamura
29

Pada tahun 2018, inilah cara Anda melakukannya:

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

Ini digunakan dalam kode Angular 6+ saya seperti:

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

Jika saya meneruskan sebuah string, itu menyalinnya. Jika tidak ada, itu menyalin URL halaman.

Lebih banyak senam untuk hal-hal clipboard dapat dilakukan juga. Lihat informasi lebih lanjut di sini:

Membuka Blokir Akses Clipboard

KhoPhi
sumber
Anda telah ditautkan ke localhost
Joe Warner
2
Perlu diketahui bahwa ini tidak berfungsi di Safari (versi 11.1.2)
arjun27
1
@ arjun27 Yah semoga suatu hari nanti Apple akan menyusul. Meskipun ini caniuse.com/#feat=clipboard menunjukkan versi di atas yang Anda sebutkan sebagian didukung.
KhoPhi
2
Saya mendapatkan untuk kedua fungsi readText, writeText a Promise dalam status yang ditolak
ramin
3
Menurut tautan yang disediakan, "navigator.clipboard hanya didukung untuk halaman yang ditayangkan melalui HTTPS"
TimH - Codidact
26

Dari salah satu proyek yang saya kerjakan, plugin jQuery copy-to-clipboard yang memanfaatkan pustaka Zero Clipboard .

Lebih mudah digunakan daripada plugin Zero Clipboard asli jika Anda adalah pengguna jQuery yang berat.

SteamDev
sumber
6
92kb tidak terlalu besar sebenarnya, ia bekerja dengan cepat & Anda dapat menggunakannya text()daripada innerHTML()jika Anda suka ..
RozzA
17
@ John: innerHTMLsudah lama mendukung cross-browser. Hanya karena Microsoft awalnya datang dengan ide itu tidak membuatnya tidak dapat diandalkan atau berpemilik. Sekarang juga akhirnya ditambahkan ke spesifikasi resmi (setelah setiap vendor browser utama sudah menambahkan dukungan untuk itu ... huh ).
James M. Greene
19
@ John Anda mengeluh tentang jQuery tidak cukup JavaScripty dalam jawaban yang menggunakan Flash;)
Max Nanasy
4
innerHTML lebih baik daripada alternatif dalam banyak kasus. Turunkan kuda tinggi Anda! Lebih cepat, lebih efisien, dan tidak memerlukan pembuatan ulang halaman.
Mengorbit Eden
4
@RozzA 92KBsangat besar. Hingga LTE jatuh tempo, GPRS adalah standar data seluler WW , dan ini dimulai pada 1 KB/s. Lakukan perhitungan sendiri.
Tino
23

Karena Chrome 42+ dan Firefox 41+ sekarang mendukung perintah document.execCommand ('copy') . Jadi saya membuat beberapa fungsi untuk kemampuan copy-to-clipboard lintas-browser menggunakan kombinasi jawaban lama Tim Down dan jawaban Pengembang Google :

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>

Jeff Baker
sumber
Terima kasih telah menyimpulkan ini! Anda memiliki sedikit kesalahan dalam kode Anda: Anda mendefinisikan variabel "range" dua kali (var range = document.createRange ()).
Christian Engel
1
Anda benar @ChristianEngel. Saya telah menghapus yang kedua. Saya tidak tahu bagaimana itu bisa masuk ke sana.
Jeff Baker
23

Saya menggunakan ini dengan sangat sukses ( tanpa jQuery atau kerangka kerja lainnya).

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

Peringatan

Tab dikonversi ke spasi (setidaknya di Chrome).

Suram
sumber
Ruang tidak ada dalam pendekatan ini
Bikram
1
Chrome. tab dikonversikan ke satu spasi
Bikram
22

Saya menemukan solusi berikut:

Pada penangan tombol bawah membuat tag "pre". Kami mengatur konten untuk disalin ke tag ini, lalu membuat pilihan pada tag ini dan mengembalikan true di handler. Ini memanggil penangan standar chrome dan menyalin teks yang dipilih.

Dan jika perlu, Anda dapat mengatur batas waktu untuk fungsi untuk mengembalikan pilihan sebelumnya. Implementasi saya di 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. :(');
     };
   }

Pemakaian:

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;

Pada paste, ia menciptakan textarea dan bekerja dengan cara yang sama.

PS mungkin solusi ini dapat digunakan untuk membuat solusi cross-browser sepenuhnya tanpa flash. Ini bekerja di FF dan Chrome.

Enyby
sumber
2
Adakah yang mencobanya? Kedengarannya seperti sesuatu yang bagus, kalau-kalau itu benar-benar berfungsi pada berbagai browser!
Michael
1
jsfiddle.net/H2FHC Demo: fiddle.jshell.net/H2FHC/show Silakan buka dan tekan Ctrl + V atau Ctrl + C. Dalam FF 19.0 garpu sempurna. Di Chrome 25.0.1364.97 m juga. Opera 12.14 - OK. Safari 5.1.7 untuk Windows - OK. IE - GAGAL.
Enyby
Untuk IE perlu menjalankan fokus pada elemen di dalam halaman. Lihat fiddle.jshell.net/H2FHC/3/show dan fiddle.jshell.net/H2FHC/3 Bekerja di IE 9/10. IE 6/7 perlu proses membuat seleksi dengan cara lain karena document.createRange tidak didukung.
Enyby
21

Metode lain akan menyalin teks biasa ke clipboard. Untuk menyalin HTML (yaitu, Anda dapat menempelkan hasilnya ke editor WSIWYG), Anda dapat melakukan hal berikut di IE ONLY . Ini pada dasarnya berbeda dari metode lain, karena browser benar-benar terlihat memilih konten.

// 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();   
Chase Seibert
sumber
lihat solusi HTML yang lebih lengkap di sini stackoverflow.com/questions/34191780/…
kofifus
21

Saya telah mengumpulkan apa yang saya pikir adalah yang terbaik.

  • Menggunakan cssText untuk menghindari pengecualian di Internet Explorer yang bertentangan dengan gaya secara langsung.
  • Kembalikan pilihan jika ada
  • Setel hanya baca agar keyboard tidak muncul di perangkat seluler
  • Memiliki solusi untuk iOS sehingga benar-benar berfungsi seperti biasanya memblokir execCommand.

Ini dia:

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

Pemakaian: copyToClipboard('some text')

Dominic
sumber
13

Pada Flash 10, Anda hanya dapat menyalin ke clipboard jika tindakan berasal dari interaksi pengguna dengan objek Flash. ( Baca bagian terkait dari pengumuman Adobe 10 Flash )

Solusinya adalah terlalu banyak objek flash di atas tombol Salin, atau elemen apa pun yang memulai salinan. Zero Clipboard saat ini adalah perpustakaan terbaik dengan implementasi ini. Pengembang Flash berpengalaman mungkin hanya ingin membuat perpustakaan sendiri.

matthuhiggins
sumber
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>

Samuel Tees
sumber
Jawaban terbaik: D, Anda dapat memperbaikinya dengan sesuatu seperti ini: #t {position: absolute; kiri: 0; z-index: -900; lebar: 0px; tinggi: 0px; perbatasan: tidak ada; } Jadi itu akan disembunyikan sepenuhnya! Tapi sungguh terima kasih kawan!
Federico Navarrete
#t {resize: none;}
SmartManoj
Penjelasan akan diurutkan.
Peter Mortensen
12

Saya menemukan solusi berikut:

Saya memiliki teks dalam input tersembunyi. Karena setSelectionRangetidak bekerja pada input tersembunyi, saya mengubah sementara jenis ke teks, menyalin teks, dan kemudian membuatnya tersembunyi lagi. Jika Anda ingin menyalin teks dari suatu elemen, Anda bisa meneruskannya ke fungsi dan menyimpan kontennya di variabel target.

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;
}
Vassilis Pallas
sumber
11

Salin teks dari input HTML ke clipboard:

 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>

Catatan: The document.execCommand()Metode tidak didukung di Internet Explorer 9 dan sebelumnya.

Sumber : W3Schools - Salin Teks ke Clipboard

Alexandru Sirbu
sumber
11

Ada banyak jawaban, namun ingin menambahkannya (jQuery). Berfungsi bagus pada peramban apa pun, juga peramban seluler (yaitu, meminta keamanan, tetapi ketika Anda menerimanya berfungsi dengan baik).

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

Dalam kode Anda:

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

Ini sedikit kombinasi antara jawaban yang lain.

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

Ini menggunakan jQuery, tetapi tentu saja tidak harus. Anda dapat mengubahnya jika Anda mau. Saya baru saja meminta jQuery. Anda juga dapat menambahkan beberapa CSS untuk memastikan input tidak muncul. Misalnya sesuatu seperti:

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

Atau tentu saja Anda juga bisa melakukan beberapa style inline

.append($('<textarea name="fname" style="opacity: 0;  position: absolute;" class="textToCopyInput"/>' )
Bart Burg
sumber
Cara menyalin langsung dari data variabel .ie: var str = "word"; ?
Pesan variabel tidak digunakan
Voyager
Lebih baik menggunakan '<textarea class = "textToCopyInput" /> </textarea>' dalam kasus textToCopyberisi\n
Voyager
8

Di browser selain IE Anda harus menggunakan objek flash kecil untuk memanipulasi clipboard, misalnya

Quog
sumber
Ini sudah ketinggalan zaman sekarang ... lihat saran oleh
GvS
6
Saran oleh GvS menggunakan film flash? Bukankah itu ide yang sama?
TheEmirOfGroofunkistan
8

Saya memiliki masalah yang sama dengan membangun edit kisi khusus (seperti Excel) dan kompatibilitas dengan Excel. Saya harus mendukung pemilihan beberapa sel, menyalin dan menempel.

Solusi: buat sebuah textarea di mana Anda akan memasukkan data untuk disalin pengguna (untuk saya ketika pengguna memilih sel), atur fokus padanya (misalnya, ketika pengguna menekan Ctrl) dan pilih seluruh teks.

Jadi, ketika pengguna menekan Ctrl+ Cdia akan menyalin sel-sel yang dia pilih. Setelah pengujian hanya mengubah ukuran textarea menjadi satu pixel (saya tidak menguji apakah itu akan berfungsi pada layar: tidak ada). Ini bekerja dengan baik di semua browser, dan transparan bagi pengguna.

Menempel - Anda bisa melakukan hal yang sama seperti ini (berbeda pada target Anda) - tetap fokus pada textarea dan menangkap acara tempel menggunakan onpaste (dalam proyek saya, saya menggunakan textareas dalam sel untuk mengedit).

Saya tidak bisa menempelkan contoh (proyek komersial), tetapi Anda mendapatkan idenya.

xiniu
sumber
7

Saya telah menggunakan clipboard.js.

Kita bisa mendapatkannya di npm:

npm install clipboard --save

Dan juga pada Bower

bower install clipboard --save

Penggunaan & contoh ada di https://zenorocha.github.io/clipboard.js/ .

CodecPM
sumber
Saya takut itu tidak kompatibel dengan konten dinamis, tetapi itu adalah :-) Saya pikir itu solusi yang lebih baik, SEKARANG, daripada yang lama tahun 2008.
BENARD Patrick
6

Ini adalah perluasan dari jawaban @ Chase, dengan keuntungan bahwa ia akan bekerja untuk elemen IMAGE dan TABLE, tidak hanya DIV pada 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');
}
Oliver Bock
sumber
5

Sepertinya saya salah membaca pertanyaan, tetapi untuk referensi, Anda dapat mengekstrak berbagai DOM (bukan ke clipboard; kompatibel dengan semua browser modern), dan menggabungkannya dengan acara oncopy dan onpaste dan onbeforepaste untuk mendapatkan perilaku clipboard. Berikut kode untuk mencapai ini:

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;
  }
}
mrBorna
sumber
1
sebenarnya saya memperbaiki kode. Ini bekerja di semua browser tetapi sebenarnya tidak menyalin ke clipboard. Cukup mengekstraksi (memotong), mengklon (menyalin) konten melalui variabel. Sepertinya saya sudah lupa penggunaannya.
mrBorna
5

Salahku. Ini hanya berfungsi di IE.

Berikut ini cara lain untuk menyalin teks:

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
dvallejo
sumber
9
Ini tidak berfungsi di Chrome saat ini (V31) atau FireFox (v25). Kesalahan adalah bahwa window.clipboardData tidak terdefinisi. Di sisi positifnya, ia bekerja di IE9. Jadi, selama Anda tidak peduli tentang peramban yang baik dan ingin mengunci situs Anda untuk menggunakan peramban yang buruk, ini adalah cara bagi Anda untuk melakukannya!
Anthony
2
saya tidak mengerti mengapa begitu banyak jawaban konyol. w3schools.com/howto/tryit.asp?filename=tryhow_js_copy_clipboard
Martian2049
5

Ini adalah satu-satunya hal yang pernah saya kerjakan, setelah mencari berbagai cara di Internet. Ini adalah topik yang berantakan. Ada banyak solusi yang diposting di seluruh dunia dan kebanyakan dari mereka tidak berfungsi. Ini bekerja untuk saya:

CATATAN: Kode ini hanya akan berfungsi ketika dijalankan sebagai kode sinkron langsung ke sesuatu seperti metode 'onClick'. Jika Anda memanggil respons asinkron ke Ajax atau dengan cara asinkron apa pun, itu tidak akan berfungsi.

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

Saya menyadari kode ini akan menunjukkan komponen lebar 1-pixel terlihat di layar selama satu milidetik, tetapi memutuskan untuk tidak khawatir tentang itu, yang merupakan sesuatu yang orang lain dapat mengatasi jika masalah nyata.

Peter Mortensen
sumber
5

Untuk menyalin teks yang dipilih ('Teks Untuk Disalin') ke clipboard Anda, buat Bookmarklet (bookmark browser yang mengeksekusi JavaScript) dan jalankan (klik di atasnya). Ini akan membuat textarea sementara.

Kode dari 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');
Mau
sumber