A very common need when building websites is the ability to copy text to clipboard with a single button click. Doing this programmatically with JavaScript is quite easy in modern browsers, using the asynchronous Clipboard API. If, however, you need to support older browsers, there is an alternative option, but it’s a little more complicated.
The Asynchronous Clipboard API
Full support for the Clipboard API still isn’t here at the time of writing (January, 2024), but you can at least use it to write to the clipboard. Thankfully, that’s all you really need. Despite support caveats, this is the recommended way to copy text to clipboard, as it provides an easy and secure solution.
All you have to do is ensure Navigator
, Navigator.clipboard
and Navigator.clipboard.writeText
are truthy and then call Clipboard.writeText()
to copy the value to clipboard. In case anything goes wrong, you can use Promise.reject()
to return a promise that rejects immediately and keep the return type consistent.
代码实现
const copyToClipboard = str => {
if (navigator && navigator.clipboard && navigator.clipboard.writeText)
return navigator.clipboard.writeText(str);
return Promise.reject('The Clipboard API is not available.');
};
If you’re concerned about browser support, you can use Promise.prototype.catch()
to handle the error and provide a fallback. The fallback could even be using the legacy method, which we’ll cover next.
Using Document.execCommand('copy')
While support for the Clipboard API is pretty high across the board, you might need a fallback if you have to support older browsers. If that’s the case, you can use Document.execCommand('copy')
to do so. Here’s a quick step-by-step guide:
- Create a
<textarea>
element to be appended to the document. Set its value to the string you want to copy to the clipboard. - Append the
<textarea>
element to the current HTML document and use CSS to hide it to prevent flashing. - Use
Selection.getRangeAt()
to store the selected range (if any). - Use
HTMLInputElement.select()
to select the contents of the<textarea>
element. - Use
Document.execCommand('copy')
to copy the contents of the<textarea>
to the clipboard. - Remove the
<textarea>
element from the document and restore the user’s previous selection, if any.
使用样例
const copyToClipboard = str => {
const el = document.createElement('textarea');
el.value = str;
el.setAttribute('readonly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);
const selected =
document.getSelection().rangeCount > 0
? document.getSelection().getRangeAt(0)
: false;
el.select();
document.execCommand('copy');
document.body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
};
[!CAUTION]
This method will not work everywhere, but only as a result of a user action (e.g. inside a
click
event listener). This is a security measure to prevent malicious websites from copying sensitive data to the clipboard without the user’s consent.
翻译自:https://www.30secondsofcode.org/js/s/copy-text-to-clipboard