如何在JavaScript中复制到剪贴板?

将文本复制到剪贴板的最佳方法是什么? (多浏览器)

我努力了:

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

但在Internet Explorer中会出现语法错误。 在Firefox中,它说unsafeWindow is not defined

编辑一个不带闪光灯的好技巧: Trello如何访问用户的剪贴板?

浏览器支持

JavaScript document.execCommand('copy')支持已经增长,请参阅下面的链接浏览器更新:

  • IE10 +(虽然这个文件表示来自IE5.5 +的一些支持)。
  • Google Chrome 43+(〜2015年4月)
  • Mozilla Firefox 41+(发货〜2015年9月)
  • Opera 29+(基于Chromium 42,2015年4月)

简单的例子

 var copyTextareaBtn = document.querySelector('.js-textareacopybtn'); copyTextareaBtn.addEventListener('click', function(event) { var copyTextarea = document.querySelector('.js-copytextarea'); 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> 

自动复制到剪贴板可能是危险的,因此大多数浏览器(IE除外)使其非常困​​难。 我个人使用以下简单的技巧:

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

用户将看到提示框,其中要复制的文本已被选中。 现在,按Ctrl + CEnter (closures框)就足够了 – 瞧!

现在剪贴板复制操作是安全的,因为用户手动(但以一个非常简单的方式)。 当然,适用于所有浏览器。

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

以下方法适用于Chrome,Firefox,Internet Explorer和Edge以及最新版本的Safari(2016年10月发布的版本10中增加了复制支持)。

  • 创build一个textarea并将其内容设置为您想要复制到剪贴板的文本。
  • 将textarea附加到DOM。
  • selecttextarea中的文本。
  • 调用document.execCommand(“copy”)
  • 从dom中删除textarea。

注意:您不会看到textarea,因为它是在同一个Javascript代码的同步调用中添加和删除的。

有些事情要注意,如果你自己实现这个:

  • 出于安全原因,这只能从一个事件处理程序,如点击(就像打开窗口)调用。
  • IE将在第一次更新剪贴板时显示权限对话框。
  • IE和Edge将在textarea聚焦时滚动。
  • execCommand()可能会抛出一些情况。
  • 除非使用textarea,换行符和制表符可能会被吞噬。 (大多数文章似乎推荐使用div)
  • 当显示IE对话框时,textarea将会显示,你可能需要隐藏它,或者使用IE特定的clipboardData API。
  • 在IE系统pipe理员可以禁用剪贴板API。

下面的函数应尽可能干净地处理以下所有问题。 如果您发现任何问题或有任何改善build议,请留下评论。

 // Copies a string to the clipboard. Must be called from within an // event handler such as click. May return false if it failed, but // this is not always possible. Browser support for Chrome 43+, // Firefox 42+, Safari 10+, Edge and IE 10+. // IE: The clipboard feature may be disabled by an administrator. By // default a prompt is shown the first time the clipboard is // used (per session). function copyToClipboard(text) { if (window.clipboardData && window.clipboardData.setData) { // IE specific code path to prevent textarea being shown while dialog is visible. return clipboardData.setData("Text", text); } else if (document.queryCommandSupported && document.queryCommandSupported("copy")) { var textarea = document.createElement("textarea"); textarea.textContent = text; textarea.style.position = "fixed"; // Prevent scrolling to bottom of page in MS Edge. document.body.appendChild(textarea); textarea.select(); try { return document.execCommand("copy"); // Security exception may be thrown by some browsers. } catch (ex) { console.warn("Copy to clipboard failed.", ex); return false; } finally { document.body.removeChild(textarea); } } } 

https://jsfiddle.net/fx6a6n6x/

如果您想要一个非常简单的解决scheme(需要不到5分钟的时间进行整合)并且看起来不错,那么Clippy是一些更复杂解决scheme的不错select。

大眼夹

它是由Github的联合创始人撰写的。 下面的示例Flashembedded代码:

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

请记住将#{text}replace为您需要复制的文本,用#{bgcolor}replace#{bgcolor}

从网页阅读和修改剪贴板引发了安全和隐私问题。 但是,在Internet Explorer中,可以这样做。 我发现这个例子片段 :

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

我最近在这个问题上写了一篇技术性的博客文章 (我在Lucidchart工作,最近我们在剪贴板上做了一个大检查)。

复制纯文本到剪贴板是相对简单的,假设你想在系统复制事件期间(用户按下ctrl-c或使用浏览器的菜单)执行它。

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

不在系统复制事件期间将文本放在剪贴板上要困难得多。 看起来这些其他答案的其中一些参考的方式通过Flash,这是唯一的跨浏览器的方式来做到这一点(据我所知)。

除此之外,还有一些浏览器浏览器的选项。

这是在IE中最简单的,你可以在Javascript中随时访问剪贴板数据对象:

 window.clipboardData 

(当您尝试在系统剪切,复制或粘贴事件之外执行此操作时,IE会提示用户授予Web应用程序剪贴板权限。)

在Chrome中,您可以创build一个Chrome扩展程序,它将为您提供剪贴板权限 (这是我们为Lucidchart执行的操作)。 那么对于安装了你的扩展的用户,你只需要自己触发系统事件:

 document.execCommand('copy'); 

它看起来像Firefox有一些选项 ,允许用户授予某些网站访问剪贴板的权限,但我没有亲自尝试任何这些。

clipboard.js是一个小的非闪存实用程序,允许将文本或html数据复制到剪贴板。 使用起来非常简单,只需包含.js文件并使用如下所示:

 <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也在GitHub上

ZeroClipboard是我find的最好的跨浏览器解决scheme:

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

如果您需要iOS版的非Flash支持,则只需添加一个回退:

 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

从我一直在研究的项目之一,jQuery的复制到剪贴板插件,利用零剪贴板库。

如果你是一个沉重的jQuery用户,比原生的Zero Clipboard插件更容易使用。

我发现了以下解决scheme:

在关键处理器上创build“pre”标签。 我们将内容设置为复制到此标记,然后对此标记进行select,并在处理程序中返回true。 这将调用铬的标准处理程序并复制选定的文本。

如果你需要,你可以设置恢复以前selectfunction的超时时间。 我在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. :('); }; } 

用法:

 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; 

在粘贴它创buildtextarea和工作方式相同。

PS可能是这个解决scheme可以用来创build完全跨浏览器的解决scheme,而不需要flash。 它的作品在FF和Chrome。

其他方法将复制纯文本到剪贴板。 要复制HTML(即,可以将结果粘贴到WSIWYG编辑器中),只能在IE中执行以下操作。 这与其他方法有着根本的区别,因为浏览器实际上可见地select内容。

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

因为最近Chrome 42+和Firefox 41+现在支持document.execCommand('copy')命令。 所以我使用Tim Down的旧回答和Google开发者的答案的组合来创build了一些跨浏览器复制到剪贴板能力的函数:

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

从Flash 10开始,如果操作源自用户与Flash对象的交互,则只能复制到剪贴板。 ( 阅读Adobe的Flash 10公告中的相关部分 )

解决scheme是在复制button上方的Flash对象,或任何元素启动复制。 零剪贴板是目前这个实现最好的库。 有经验的Flash开发人员可能只想制作自己的图书馆。

我发现了以下解决scheme:

我有一个隐藏的input文本。 因为setSelectionRange不能在隐藏的input上工作,所以我暂时将types改为文本,复制文本然后再次隐藏。 如果要从元素中复制文本,可以将其传递给函数,并将其内容保存到目标variables中。

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

在除IE以外的浏览器中,您需要使用一个小的Flash对象来操作剪贴板,例如

  • 自动复制到剪贴板
  <!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> 

This is an expansion of @Chase's answer, with the advantage that it will work for IMAGE and TABLE elements, not just DIVs on 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'); } 

I had the same problem building a custom grid edit from (something like Excel) and compatibility with Excel. I had to support selecting multiple cells, copying and pasting.

Solution: create a textarea where you will be inserting data for the user to copy (for me when the user is selecting cells), set focus on it (for example, when user press Ctrl ) and select the whole text.

So, when the user hit Ctrl + C he gets copied cells he selected. After testing just resizing the textarea to 1 pixel (I didn't test if it will be working on display:none). It works nicely on all browsers, and it is transparent to the user.

Pasting – you could do same like this (differs on your target) – keep focus on textarea and catch paste events using onpaste (in my project I use textareas in cells to edit).

I can't paste an example (commercial project), but you got the idea.

I have used clipboard.js

we can get it on npm

 npm install clipboard --save 

and also on bower

 bower install clipboard --save 

Usage & examples are at https://zenorocha.github.io/clipboard.js/

ng-clip was the simplest solution for AngularJS.

Many answers already but I like to add one (jQuery). Works like a charm on any browser, also mobile ones (ie prompts about security but when you accept it just works fine).

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

In your code:

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

I found another nice solution LMCButton – small animated flash cross browser button. One JavaScript functions and swf button. Simple options (caption, custom JavaScript).

Link: Copy to Clipboard LMCButton

我的错。 This only works in IE.

Here's yet another way to copy text:

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

I had to copy the non-input boxes text (text within any div/span tag) from the page and came up with following code. Only trick is to have a hidden field but as type TEXT, wont work with type hidden.

  function copyToClipboard(sID) { var aField = document.getElementById("hiddenField"); aField.hidden = false; aField.value = document.getElementById(sID).textContent; aField.select(); document.execCommand("copy"); alert("Following text has been copied to the clipboard.\n\n" + aField.value); aField.hidden = true; } 

And in the HTML add the following

input type="text" id="hiddenField" style="width:5px;border:0" /> …

I would like to share my solution too, it's a bit of a combination between the other answers.

 var copyToClipboard = function(textToCopy){ $("body") .append($('<input type="text" 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(); } 

It uses jQuery but it doesn't have to of course, you can change that if you want. I just had jQuery to my disposal. You can also add some CSS to make sure the input doesn't show. For instance something like:

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

Or ofcourse you could also do some inline styling

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

Here is my take on that one..

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

Looks like you took the code from Greasemonkey\JavaScript Copy to Clipboard button or the original source of this snippet…

This code was for Greasemonkey, hence the unsafeWindow. And I guess the syntax error in IE comes from the const keyword which is specific to Firefox (replace it with var ).

It seems I misread the question, but for reference, you can extract a range of the DOM (not to clipboard; compatible with all modern browsers), and combine it with the oncopy and onpaste and onbeforepaste events to get clipboard behaviour. Here's the code to achieve this:

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

As far as I know that only works in Internet Explorer.

See also Dynamic Tools – JavaScript Copy To Clipboard , but it requires the user to change the configuration first and even then it doesn't seems to work.

Update 2015: currently theres a way to use document.execCommand to work with the clipboard. clipboard.js provides a cross browser way to work with the clipboard ( browser support )