Update 2020: This solution uses execCommand
. While that feature was fine at the moment of writing this answer, it is now considered obsolete. It will still work on many browsers, but its use is discouraged as support may be dropped.
There is another non-Flash way (apart from the Clipboard API mentioned in jfriend00's answer). You need to select the text and then execute the command copy
to copy to the clipboard whatever text is currently selected on the page.
For example, this function will copy the content of the passed element into the clipboard (updated with suggestion in the comments from PointZeroTwo):
function copyToClipboard(element) {
var $temp = $("<input>");
$("body").append($temp);
$temp.val($(element).text()).select();
document.execCommand("copy");
$temp.remove();
}
This is how it works:
- Creates a temporarily hidden text field.
- Copies the content of the element to that text field.
- Selects the content of the text field.
- Executes the command copy like:
document.execCommand("copy")
.
- Removes the temporary text field.
NOTE that the inner text of the element can contain whitespace. So if you want to use if for example for passwords you may trim the text by using $(element).text().trim()
in the code above.
You can see a quick demo here:
function copyToClipboard(element) {
var $temp = $("<input>");
$("body").append($temp);
$temp.val($(element).text()).select();
document.execCommand("copy");
$temp.remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id="p1">P1: I am paragraph 1</p>
<p id="p2">P2: I am a second paragraph</p>
<button onclick="copyToClipboard('#p1')">Copy P1</button>
<button onclick="copyToClipboard('#p2')">Copy P2</button>
<br/><br/><input type="text" placeholder="Paste here for test" />
The main issue is that not all browsers support this feature at the moment, but you can use it on the main ones from:
- Chrome 43
- Internet Explorer 10
- Firefox 41
- Safari 10
Update 1: This can be achieved also with a pure JavaScript solution (no jQuery):
function copyToClipboard(elementId) {
// Create a "hidden" input
var aux = document.createElement("input");
// Assign it the value of the specified element
aux.setAttribute("value", document.getElementById(elementId).innerHTML);
// Append it to the body
document.body.appendChild(aux);
// Highlight its content
aux.select();
// Copy the highlighted text
document.execCommand("copy");
// Remove it from the body
document.body.removeChild(aux);
}
<p id="p1">P1: I am paragraph 1</p>
<p id="p2">P2: I am a second paragraph</p>
<button onclick="copyToClipboard('p1')">Copy P1</button>
<button onclick="copyToClipboard('p2')">Copy P2</button>
<br/><br/><input type="text" placeholder="Paste here for test" />
Notice that we pass the id without the # now.
As madzohan reported in the comments below, there is some strange issue with the 64-bit version of Google Chrome in some cases (running the file locally). This issue seems to be fixed with the non-jQuery solution above.
Madzohan tried in Safari and the solution worked but using document.execCommand('SelectAll')
instead of using .select()
(as specified in the chat and in the comments below).
As PointZeroTwo points out in the comments, the code could be improved so it would return a success/failure result. You can see a demo on this jsFiddle.
UPDATE: COPY KEEPING THE TEXT FORMAT
As a user pointed out in the Spanish version of StackOverflow, the solutions listed above work perfectly if you want to copy the content of an element literally, but they don't work that great if you want to paste the copied text with format (as it is copied into an input type="text"
, the format is "lost").
A solution for that would be to copy into a content editable div
and then copy it using the execCommand
in a similar way. Here there is an example - click on the copy button and then paste into the content editable box below:
function copy(element_id){
var aux = document.createElement("div");
aux.setAttribute("contentEditable", true);
aux.innerHTML = document.getElementById(element_id).innerHTML;
aux.setAttribute("onfocus", "document.execCommand('selectAll',false,null)");
document.body.appendChild(aux);
aux.focus();
document.execCommand("copy");
document.body.removeChild(aux);
}
#target {
width:400px;
height:100px;
border:1px solid #ccc;
}
<p id="demo"><b>Bold text</b> and <u>underlined text</u>.</p>
<button onclick="copy('demo')">Copy Keeping Format</button>
<div id="target" contentEditable="true"></div>
And in jQuery, it would be like this:
function copy(selector){
var $temp = $("<div>");
$("body").append($temp);
$temp.attr("contenteditable", true)
.html($(selector).html()).select()
.on("focus", function() { document.execCommand('selectAll',false,null); })
.focus();
document.execCommand("copy");
$temp.remove();
}
#target {
width:400px;
height:100px;
border:1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id="demo"><b>Bold text</b> and <u>underlined text</u>.</p>
<button onclick="copy('#demo')">Copy Keeping Format</button>
<div id="target" contentEditable="true"></div>