66

Premise

I need help copying rich text to the clipboard using JavaScript. I have searched around and haven't found anything to suit my specific needs.

Code

function ctrlA1(corp) {
  with(corp) {}
  if (document.all) {
    txt = corp.createTextRange()
    txt.execCommand("Copy")
  } else
    setTimeout("window.status=''", 5000)
}
<div id="sc1">hello <br> <b> world </b> </div>
<button onclick="ctrlA1(document.getElementById('sc1') )"></button>

Problem

The aforementioned code isn't working and is resulting in an object expected error. Any help is appreciated! I have seen a library out there called zeroclipboard, but would prefer to write my own function.


Edit:

I now have this function to select text on the page. is it possible to write a formula to copy the selected range as is?

function containerSelect(id) {
  containerUnselect();
  if (document.selection) {
    var range = document.body.createTextRange();
    range.moveToElementText(id);
    range.select();
  } else if (window.getSelection) {
    var range = document.createRange();
    range.selectNode(id);
    window.getSelection().addRange(range);
  }
}
<label onclick="containerSelect(this); select_all()">
  <p>hello world</p>
  <img src="imagepath.png">
</label>
isherwood
  • 58,414
  • 16
  • 114
  • 157
marv
  • 962
  • 3
  • 9
  • 17
  • BTW, ['Use of the with statement is not recommended, as it may be the source of confusing bugs and compatibility issues.'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with) – Andy May 29 '14 at 13:38
  • Solution with JS only, See http://jsfiddle.net/jdhenckel/km7prgv4/3 – John Henckel Dec 14 '17 at 17:57

6 Answers6

96

With modern browsers, if you want copy rich text only, there is a very easy solution without using any packages. See http://jsfiddle.net/jdhenckel/km7prgv4/3

Here is the source code from the fiddle

<button onclick="copyToClip(document.getElementById('foo').innerHTML)">
  Copy the stuff
  </button>
  
<div id=foo style="display:none">
  This is some data that is not visible. 
  You can write some JS to generate this data. 
  It can contain rich stuff.  <b> test </b> me <i> also </i>
  <span style="font: 12px consolas; color: green;">Hello world</span> 
  You can use setData to put TWO COPIES into the same clipboard, 
  one that is plain and one that is rich. 
  That way your users can paste into either a
  <ul>
    <li>plain text editor</li>
    <li>or into a rich text editor</li>
  </ul>
</div>

the function

function copyToClip(str) {
  function listener(e) {
    e.clipboardData.setData("text/html", str);
    e.clipboardData.setData("text/plain", str);
    e.preventDefault();
  }
  document.addEventListener("copy", listener);
  document.execCommand("copy");
  document.removeEventListener("copy", listener);
};

⚠️ ClipboardEvent.clipboardData is experimental technology. Check the browser compatibility table in MDN (05-03-21)

JTorleon
  • 108
  • 1
  • 9
John Henckel
  • 10,274
  • 3
  • 79
  • 79
  • Thank you. I tested this by copying and pasting into Word. It works beautifully on Chrome. It does not seem to work on IE11 at all. On Edge it will paste the text but without formatting. – gordon613 May 30 '18 at 14:37
  • Sorry about that. I didn't test it on IE 11 or edge. I wonder... if you reverse the two `e.clipboardData.setData` then perhaps you can paste rich text with IE edge... ? just a thought – John Henckel May 31 '18 at 21:22
  • 2
    Doesn't work in Safari 11.1.1. Nothing copies, whatever was previously on the clipboard is still there. – John Smith Jun 11 '18 at 07:47
  • 1
    This works for me in FF, Chrome, Edge, and IE11. IE11 prompts the user if to allow access to the clipboard. It does not work in Safari. Another method is required for that, and as far as I can tell you can't copy the "rich text", just plain text. – Mmm Aug 22 '18 at 21:24
  • 3
    You can use a little bit modified code to also provide text-only version for editors that can not render html: http://jsfiddle.net/kt4jdm95/1/ – SleepWalker Mar 29 '22 at 12:52
12

This tiny JS plugin copies richtext without using Flash: https://www.npmjs.com/package/clipboard-js

It's based on https://clipboardjs.com/ - but it's an upgrade in my opinion, because the original only supports plain text.

The code is simple:

clipboard.copy({
    "text/html": "<i>Markup</i> <b>text</b>. Paste me into a rich text editor."
});
SFlagg
  • 379
  • 5
  • 10
4

Here is an example I tested using the new Clipboard API:

const content = '<a href="http://google.com/">test</a>';
const blob = new Blob([content], {type: 'text/html'});
const clipboardItem = new window.ClipboardItem({ 'text/html': blob });
navigator.clipboard.write([clipboardItem]);

Using this method, you can copy html to the clipboard. One useful thing to note is that this can include images (which can be dataURLs). This is the only way I found to paste multiple images to the clipboard.

antoineMoPa
  • 854
  • 10
  • 20
  • 1
    This does not work on Firefox. Please see my [answer](https://stackoverflow.com/a/74216984/4493592) in a [similar post](https://stackoverflow.com/questions/34191780/javascript-copy-string-to-clipboard-as-text-html/74216984#74216984). – tst Oct 27 '22 at 05:00
  • If trying this in the console, it may fail because the document itself doesn't have focus, in which case you might need to put this code in a `setTimeout` so that you have time to move focus back to the document. – BallpointBen Mar 21 '23 at 16:21
1

Here's an old Flash-based solution. Due to the discontinuation of Flash, it should no longer be used in production environments.

https://github.com/zeroclipboard/zeroclipboard

Pikamander2
  • 7,332
  • 3
  • 48
  • 69
James Harrington
  • 3,138
  • 30
  • 32
  • The OP mentions zeroclipboard in his question, and I talk about it in my comment. – Andy May 29 '14 at 13:44
  • i just figured id offer an answer. Since there is no reliable JS method for doing it – James Harrington May 29 '14 at 13:55
  • @codenamejames: ok, i tried using the help on ZC and dont think i'm being very successful here. here is my code which isnt working still :( – marv May 29 '14 at 16:53
  • Copy To Clipboard ` – marv May 29 '14 at 16:55
  • i think it should be more like this ```ZeroClipboard.config({ moviePath: "ZeroClipboard.swf" }); var client = new ZeroClipboard(document.getElementById('d_clip_button'));``` – James Harrington Jun 03 '14 at 13:56
  • @codenamejames that didnt work unfortunately. get an "object doesnt support this method" error. I have another function that selects text/images on the webpage (edited my post above). can i now write a function to copy the selected range? – marv Jun 05 '14 at 16:29
  • @codenamejames the last function i posted works fine, just need to know how to copy that selected text :p – marv Jun 05 '14 at 16:34
-2

i searched for a week now and finally found my answer!!! for those of you looking to copy rich text to the clipboard with javascript, then use the function at the link below, works like a charm. no need of flash and other stuff suggested :)

Copying an image to clipboard using JavaScript/jquery

Community
  • 1
  • 1
marv
  • 962
  • 3
  • 9
  • 17