原文:https://www.5axxw.com/wiki/content/eklia8

使网上复制变得简单:

clipboard.writeText("hello world");

这个库是现代基于Promise的异步剪贴板API的polyfill。

注意:截至2020年6月底,您可以在所有主流浏览器的稳定版本中使用navigator.clipboard.writeText("hello world);(请参阅下面的兼容性)。只有当您1)需要复制text/html,或者2)需要针对旧的浏览器时,这个库才会对您有用。

Usage

如果使用npm,请安装:

npm install clipboard-polyfill

将文本复制到剪贴板的示例应用程序:

// Using the `clipboard/text` build saves code size.
// This is recommended if you only need to copy text.
import * as clipboard from "clipboard-polyfill/text";

function handler() {
  clipboard.writeText("This text is plain.").then(
    function () {
      console.log("success!");
    },
    function () {
      console.log("error!");
    }
  );
}

window.addEventListener("DOMContentLoaded", function () {
  const button = document.createElement("button");
  button.textContent = "Copy";
  button.addEventListener("click", handler);
  document.body.appendChild(button);
});

Notes:

  • 您需要调用剪贴板操作以响应用户手势(例如,button单击的事件处理程序)。有些浏览器可能只允许每个手势执行一次剪贴板操作。

async/await syntax

import * as clipboard from "clipboard-polyfill/text";

async function handler() {
  console.log("Previous clipboard text:", await clipboard.readText());

  await clipboard.writeText("This text is plain.");
}

window.addEventListener("DOMContentLoaded", function () {
  const button = document.createElement("button");
  button.textContent = "Copy";
  button.addEventListener("click", handler);
  document.body.appendChild(button);
});

更多MIME类型(数据类型)

import * as clipboard from "clipboard-polyfill";

async function handler() {
  console.log("Previous clipboard contents:", await clipboard.read());

  const item = new clipboard.ClipboardItem({
    "text/html": new Blob(
      ["<i>Markup</i> <b>text</b>. Paste me into a rich text editor."],
      { type: "text/html" }
    ),
    "text/plain": new Blob(
      ["Fallback markup text. Paste me into a rich text editor."],
      { type: "text/plain" }
    ),
  });
  await clipboard.write([item]);
}

window.addEventListener("DOMContentLoaded", function () {
  const button = document.createElement("button");
  button.textContent = "Copy";
  button.addEventListener("click", handler);
  document.body.appendChild(button);
});

有关详细信息,请查看剪贴板API规范。

Notes:

  • 对于await语法,您需要使用async函数。
  • 目前,text/plaintext/html是大多数浏览器中唯一可以写入剪贴板的数据类型。
  • 如果您试图复制不受支持的数据类型,它们可能会被自动删除(例如Safari 13.1),或者调用可能会抛出错误(例如Chrome 83)。一般来说,无法判断何时删除数据类型。
  • 在当前的一些浏览器中,read()可能只返回支持的数据类型的子集,即使剪贴板包含更多的数据类型。无法判断是否有更多的数据类型。

overwrite-globals version

如果希望库用它的实现覆盖全局剪贴板API,请导入clipboard-polyfill/overwrite-globals。这将把库从ponyfill转换为正确的polyfill,因此您可以编写代码,就好像您的浏览器中已经实现了异步剪贴板API一样:

import "clipboard-polyfill/overwrite-globals";

async function handler() {
  const item = new window.ClipboardItem({
    "text/html": new Blob(
      ["<i>Markup</i> <b>text</b>. Paste me into a rich text editor."],
      { type: "text/html" }
    ),
    "text/plain": new Blob(
      ["Fallback markup text. Paste me into a rich text editor."],
      { type: "text/plain" }
    ),
  });

  navigator.clipboard.write([item]);
}

window.addEventListener("DOMContentLoaded", function () {
  const button = document.createElement("button");
  button.textContent = "Copy";
  button.addEventListener("click", handler);
  document.body.appendChild(button);
});

不建议使用这种方法,因为它可能会破坏与剪贴板API全局变量交互的任何其他代码,并且可能与将来的浏览器实现不兼容。

Flat-file版本,包括Promise

如果您需要获取一个“只起作用”的版本,请下载clipboard-polyfill.promise.js并使用<script>标记将其包括在内:

<script src="./clipboard-polyfill.promise.js"></script>
<button onclick="copy()">Copy text!</button>
<script>
  // `clipboard` is defined on the global `window` object.
  function copy() {
    clipboard.writeText("hello world!");
  }
</script>

Why clipboard-polyfill?

随着时间的推移,浏览器已经实现了几个剪贴板API,在各种旧的和当前的浏览器中写入剪贴板而不触发bug是相当困难的。在每一个支持以某种方式复制到剪贴板的浏览器中,clipboard-polyfill都试图尽可能靠近异步剪贴板API。(请参阅上面的免责声明和limitations.)

有关在web上访问剪贴板的较长历史记录,请参阅此演示文稿。

Compatibility

  • ☑️ :浏览器具有本机异步剪贴板支持。
  • ✅ :clipboard-polyfill提供支持。
  • ❌ :无法支持。
  • 粗体浏览器名称表示现代浏览器稳定版本的最新功能更改。

最早浏览器版本的写入支持:

BrowserwriteText()write() (HTML)write() (other formats)
Safari 13.1 ☑️ ☑️ ☑️ (image/uri-listimage/png)
铬76ᵃ/边缘79 ☑️ ☑️ (image/png)
Chrome 66ᵃ/火狐63 ☑️
Safari 10/Chrome 42ᵃ/Edgeᵈ/Firefox 41 ✅ ᵇ
IE 9 ✅ ᶜ

Read support:

BrowserreadText()read() (HTML)read() (other formats)
Safari 13.1 ☑️ ☑️ ☑️ (image/uri-listimage/png)
铬76ᵃ/边缘79 ☑️ ☑️ (image/png)
Chrome 66 ☑️
IE 9 ✅ ᶜ
Firefox
  • ᵃ还包括基于相应版本Chrome的Edge、Opera、Brave、Vivaldi等版本。
  • ᵇ在版本10的前几个版本中,HTML在mobile Safari上无法正常工作。
  • ᶜ在Internet Explorer中,如果希望库正常工作,则需要polyfillwindow.Promise
  • ᵈ在旧版本的Edge(Spartan):可能无法判断复制操作是否成功(Edge Bug#14110451,Edge Bug#14080262)。clipboard-polyfill在这种情况下将始终报告成功。只有您指定的最后一种数据类型才会复制到剪贴板(Edge Bug#14080506)。考虑将最重要的数据类型放在传递给ClipboardItem构造函数的对象中。text/html数据类型不是使用预期的CF_HTML格式编写的。clipboard-polyfill没有尝试解决这个问题,因为1)它需要脆弱的浏览器版本嗅探,2)Edge的用户通常不会停留在版本17以下,3)其他浏览器的失败模式是复制无效的剪贴板HTML。(边缘缺陷14372529,73)

clipboard-polyfill使用各种启发式方法来解决兼容性问题。如果您与上面列出的任何浏览器有兼容性问题,请告诉我们。

这太复杂了!

如果你只需要复制文本,试试这个要点以获得更简单的解决方案。

或者,如果等到iOS14/MacOS11,navigator.clipboard.writeText()将在所有主流现代浏览器的稳定版本中得到支持。

posted on 2021-09-01 18:21  1183788267  阅读(1052)  评论(0编辑  收藏  举报