Warum kann auf Android-Geräten Text nicht erfolgreich in die Zwischenablage kopiert werden, wenn „alert()' vor „navigator.clipboard.writeText' steht?
P粉386318086
P粉386318086 2023-08-22 19:21:37
0
2
639
<p>Wenn ich versuche, Text mit <code>navigator.clipboard.writeText()</code> in Chrome auf Android zu kopieren, funktioniert es einwandfrei, solange ich das Warnfeld danach nicht zeige. Sobald ich einen Alert() anzeige, funktioniert es nicht mehr. </p> <p>Der folgende Code funktioniert beispielsweise wie erwartet: </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>Der folgende Code funktioniert jedoch nicht, löst keine Fehler in der Konsole aus und funktioniert einwandfrei auf Chrome auf dem PC, jedoch nicht auf 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 erfolgreich kopiert") }</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>Weiß jemand, was passiert ist? Danke. </p>
P粉386318086
P粉386318086

Antworte allen(2)
P粉354948724

原因 navigator.clipboard.writetext 不起作用的原因:

  1. 兼容性问题:在废弃了 document.exec("copy") 方法后,此方法是后来添加的。在 某些浏览器版本 中,此方法将不起作用,您应该检查此方法是否可用。

  2. 文档未聚焦:如果您在没有任何用户交互的情况下将内容写入剪贴板,浏览器将阻止您的请求,并在此方法的 Promise 中抛出错误。想象一下,用户想要复制一个您从互联网上加载的字符串(ajax)。如果此 ajax 请求花费了一点时间,浏览器的焦点将会过期,我的经验是无法完成复制。

  3. 未授权的权限:有时用户可能通过编辑其隐私和安全设置来阻止浏览器自动复制到剪贴板。在进行复制之前,请检查写入剪贴板的权限。但是,当页面处于活动选项卡时,clipboard-write 权限会自动授予页面。

  4. 异步问题:复制到剪贴板是一个异步操作,您应该等待您的代码完成工作。

  5. HTTP 网站:此功能仅在安全上下文(HTTPS)中可用,在某些或所有支持的浏览器中。

  6. Apple Safari 问题:苹果的 Clipboard API 大多数情况下期望一个 Promise 在写入剪贴板时。因此,我们可以使用 ClipboardItem 将一个 Promise 传递给 write 方法。我建议您使用 write 而不是 writeText

说话容易,展示给我 代码

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!"));
        }
    });
    
}

用法

try {
    await copy("Hay yah!");
}
catch(e) {
    console.error(e);
}

重要提示:通过按钮和 onclick 事件进行测试,而不是在控制台中。

P粉759457420

因为navigator.clipboard.writeText方法返回一个Promise,而你的代码没有等待它的结果。

如果你按照下面的代码进行修正,应该就没问题了:

function myFunction() {
    var copyText = document.getElementById("myInput");
    copyText.select();
    copyText.setSelectionRange(0, 99999);
    navigator.clipboard
      .writeText(copyText.value)
      .then(() => {
        alert("成功复制");
      })
      .catch(() => {
        alert("出了点问题");
      });
}

有关Promisenavigator.clipboard.writeText方法的更多信息,请访问以下链接:
JavaScript.info上的Promise
MDN上与剪贴板交互

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage