Why on Android devices, if there is `alert()` before `navigator.clipboard.writeText`, it cannot successfully copy text to the clipboard?
P粉386318086
P粉386318086 2023-08-22 19:21:37
0
2
612
<p>When trying to copy some text using <code>navigator.clipboard.writeText()</code> on Chrome on Android, it works fine as long as I don't show the alert box afterwards. Once I display an alert() it doesn't work anymore. </p> <p>For example, the following code works as expected: </p> <p><br /></p> <pre class="brush:js;toolbar:false;">function myFunction() { var copyText = document.getElementById("myInput"); copyText.select(); copyText.setSelectionRange(0, 99999); navigator.clipboard.writeText(copyText.value); }</pre> <pre class="brush:html;toolbar:false;"><input type="text" value="Hello world" id="myInput" style="width:auto"> <button onclick="myFunction()">copy</button></pre> <p><br /></p> <p>However the code below does not work, does not throw any errors in the console, and works fine on Chrome on PC, but not on Android. </p> <p><br /></p> <pre class="brush:js;toolbar:false;">function myFunction() { var copyText = document.getElementById("myInput"); copyText.select(); copyText.setSelectionRange(0, 99999); navigator.clipboard.writeText(copyText.value); alert("Text copied successfully") }</pre> <pre class="brush:html;toolbar:false;"><input type="text" value="Hello world" id="myInput" style="width:auto" > <button onclick="myFunction()" >copy</button></pre> <p><br /></p> <p>Does anyone know what happened? Thanks. </p>
P粉386318086
P粉386318086

reply all(2)
P粉354948724

Reasons navigator.clipboard.writetext Reasons why it doesn’t work:

  1. 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.

  2. 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.

  3. 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.

  4. Async Issues: Copying to the clipboard is an asynchronous operation, you should wait for your code to finish its work.

  5. HTTP Website: This feature is only available in a secure context (HTTPS), in some or all supported browsers.

  6. 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粉759457420

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

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!