There are many third-party plug-ins that can implement the copy function, but if we do it ourselves, do we know how to implement it?
This article introduces three implementation options.
Using Async Clipboard API
This method is the easiest to use, but the compatibility is not very good and there are many requirements.
Sample code:
const promise = navigator.clipboard.writeText(newClipText);
Note that the return value of the method is a Promise. And when using this method, the page must be in focus, otherwise an error will be reported.
uses Document.execCommand.
Although this method has been abandoned and is no longer a web standard, it has many historical factors and I believe browsers will support it for a long time.
<p id="content">123456</p> <button id="copyButton">Copy</button>
When copying DOM elements, you need to use the selection API and Range API additionally.
developer.mozilla.org/en-US/docs/…
developer.mozilla.org/en-US/docs/…
Sample code:
const copyButton = document.getElementById('copyButton'); const content = document.getElementById('content'); copyButton.addEventListener('click', function () { const selection = window.getSelection(); const range = document.createRange(); //Set the selected content range.selectNodeContents(content); // Clear the selection selection.removeAllRanges(); //Add selected content selection.addRange(range); document.execCommand('copy'); });
The selection needs to be cleared first and then the range is added.
There is a detail issue here. After clicking the copy button, the copied content is selected, which is a bit abrupt.
The solution is to call selection.removeAllRanges()
after copying is completed to clear the selection.
Consider another situation where the user selects part of the page before copying it. After the copy is completed, in addition to clearing the selected copy content, you also need to restore the content that the user selected before copying.
The implementation code is as follows:
const copyButton = document.getElementById('copyButton'); const content = document.getElementById('content'); copyButton.addEventListener('click', function () { const selection = window.getSelection(); const range = document.createRange(); //Cache the content selected by the user const currentRange = selection.rangeCount === 0 ? null : selection.getRangeAt(0); //Set document fragment range.selectNodeContents(content); // Clear the selection selection.removeAllRanges(); //Set the document fragment as the selected content selection.addRange(range); try { // Copy to clipboard document.execCommand('copy'); } catch (err) { // Prompt that copy failed} finally { selection.removeAllRanges(); if (currentRange) { //Restore user selected content selection.addRange(currentRange); } } });
First cache the content selected by the user, and then restore it after the copy is completed.
and use the select
method of the input element object to select the content. There is no need to create a range fragment to set the selected content.
Example code:
const copyButton = document.getElementById('copyButton'); const inputEl = document.getElementById('input'); copyButton.addEventListener('click', function () { const selection = window.getSelection(); const currentRange = selection.rangeCount === 0 ? null : selection.getRangeAt(0); //Select the input content inputEl.select(); //Copy to clipboard try { document.execCommand('copy'); } catch (err) { // Prompt that copy failed // . . . } finally { selection.removeAllRanges(); if (currentRange) { //Restore user selected content selection.addRange(currentRange); } } });
Clicking the copy button will also not remove the previously selected content.
w3c.github.io/clipboard-a…
Quote a piece of code in the above link as an example:
// Overwrite what is being copied to the clipboard. document.addEventListener('copy', function (e) { // e.clipboardData is initially empty, but we can set it to the // data that we want copied onto the clipboard. e.clipboardData.setData('text/plain', 'Western scrambled eggs'); // This is necessary to prevent the current document selection from // being written to the clipboard. e.preventDefault(); });
Copy any content on the page and paste the output content will be "Western scrambled eggs".