P粉3549487242023-08-23 18:36:44
Reasons navigator.clipboard.writetext
Reasons why it doesn’t work:
Compatibility issue: This method was added later after the document.exec("copy")
method was deprecated. In certain browser versions this method will not work and you should check if this method is available.
Document not focused: If you write content to the clipboard without any user interaction, the browser will block your request and throw a Promise in this method mistake. Imagine that the user wants to copy a string (ajax
) that you loaded from the internet. If this ajax
request takes a while, the browser focus will expire and my experience is that the copy cannot be completed.
Unauthorized Permissions: Sometimes users may prevent the browser from automatically copying to the clipboard by editing their privacy and security settings. Before copying, check permissions to write to the clipboard. However, clipboard-write
permission is automatically granted to the page when it is in the active tab.
Async Issues: Copying to the clipboard is an asynchronous operation, you should wait for your code to finish its work.
HTTP Website: This feature is only available in a secure context (HTTPS), in some or all supported browsers.
Apple Safari Issue: Apple's Clipboard API most of the time expects a Promise
when writing to the clipboard. Therefore, we can use ClipboardItem
to pass a Promise
to the write
method. I suggest you use write instead of writeText
Easy to talk, show me Code:
function copy(text) { return new Promise((resolve, reject) => { if (typeof navigator !== "undefined" && typeof navigator.clipboard !== "undefined" && navigator.permissions !== "undefined") { const type = "text/plain"; const blob = new Blob([text], { type }); const data = [new ClipboardItem({ [type]: blob })]; navigator.permissions.query({name: "clipboard-write"}).then((permission) => { if (permission.state === "granted" || permission.state === "prompt") { navigator.clipboard.write(data).then(resolve, reject).catch(reject); } else { reject(new Error("Permission not granted!")); } }); } else if (document.queryCommandSupported && document.queryCommandSupported("copy")) { var textarea = document.createElement("textarea"); textarea.textContent = text; textarea.style.position = "fixed"; textarea.style.width = '2em'; textarea.style.height = '2em'; textarea.style.padding = 0; textarea.style.border = 'none'; textarea.style.outline = 'none'; textarea.style.boxShadow = 'none'; textarea.style.background = 'transparent'; document.body.appendChild(textarea); textarea.focus(); textarea.select(); try { document.execCommand("copy"); document.body.removeChild(textarea); resolve(); } catch (e) { document.body.removeChild(textarea); reject(e); } } else { reject(new Error("None of copying methods are supported by this browser!")); } }); }
usage:
try { await copy("Hay yah!"); } catch(e) { console.error(e); }
Important Tip: Test via buttons and onclick
events, not in the console.
P粉7594574202023-08-23 15:36:33
Because the navigator.clipboard.writeText
method returns a Promise, and your code does not wait for its result.
If you correct it according to the following code, you should be fine:
function myFunction() { var copyText = document.getElementById("myInput"); copyText.select(); copyText.setSelectionRange(0, 99999); navigator.clipboard .writeText(copyText.value) .then(() => { alert("成功复制"); }) .catch(() => { alert("出了点问题"); }); }
For more information about the Promise
and navigator.clipboard.writeText
methods, please visit the following link:
Promise on JavaScript.info
Interacting with the clipboard on MDN