clipboard-polyfill
clipboard-polyfill
来复制文本!注意:从 2020 年开始,您可以在所有主要浏览器的稳定版本中使用navigator.clipboard.writeText(...)
。仅当您想要执行以下操作时,该库才会对您有用:
text/html
≤126,ClipboardItem
API,或者jsdom
中)填充 API 形状。有关更多详细信息,请参阅下面的兼容性部分。
使网络复制变得如此简单:
clipboard . writeText ( "hello world" ) ;
该库是用于现代基于Promise
的异步剪贴板 API 的 ponyfill/polyfill。
如果您使用npm
,请安装:
npm install clipboard-polyfill
将文本复制到剪贴板的示例应用程序:
import * as clipboard from "clipboard-polyfill" ;
function handler ( ) {
clipboard . writeText ( "This text is plain." ) . then (
( ) => { console . log ( "success!" ) ; } ,
( ) => { console . log ( "error!" ) ; }
) ;
}
window . addEventListener ( "DOMContentLoaded" , function ( ) {
const button = document . body . appendChild ( document . createElement ( "button" ) ) ;
button . textContent = "Copy" ;
button . addEventListener ( "click" , handler ) ;
} ) ;
笔记:
button
的事件处理程序)。async
/ await
语法 import * as clipboard from "clipboard-polyfill" ;
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 . body . appendChild ( document . createElement ( "button" ) ) ;
button . textContent = "Copy" ;
button . addEventListener ( "click" , handler ) ;
} ) ;
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 . body . appendChild ( document . createElement ( "button" ) ) ;
button . textContent = "Copy" ;
button . addEventListener ( "click" , handler ) ;
} ) ;
检查剪贴板 API 规范以获取更多详细信息。
笔记:
await
语法使用async
函数。text/plain
和text/html
是大多数浏览器中唯一可以写入剪贴板的数据类型。read()
可能只返回支持的数据类型的子集,即使剪贴板包含更多数据类型。无法判断是否有更多数据类型。overwrite-globals
版本如果您希望库用其实现覆盖全局剪贴板 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 . body . appendChild ( document . createElement ( "button" ) ) ;
button . textContent = "Copy" ;
button . addEventListener ( "click" , handler ) ;
} ) ;
不建议使用这种方法,因为它可能会破坏与剪贴板 API 全局变量交互的任何其他代码,并且可能与未来的浏览器实现不兼容。
Promise
的平面文件版本如果您需要获取“正常工作”的版本,请下载clipboard-polyfill.window-var.promise.es5.js
并使用<script>
标记包含它:
< script src =" ./clipboard-polyfill.window-var.promise.es5.js " > </ script >
< button onclick =" copy() " > Copy text! </ button >
< script >
// `clipboard` is defined on the global `window` object.
function copy ( ) {
clipboard . writeText ( "hello world!" ) ;
}
</ script >
由于现代 JS 生态系统的便利,我们不再提供 tree shake、minified 或 CommonJS 构建。要在不失去兼容性的情况下获得此类构建,请通过esbuild
传递clipboard-polyfill
构建。例如:
mkdir temp && cd temp && npm install clipboard-polyfill esbuild
# Minify the ES6 build:
echo ' export * from "clipboard-polyfill"; ' | npx esbuild --format=esm --target=es6 --bundle --minify
# Include just the `writeText()` export and minify:
echo ' export { writeText } from "clipboard-polyfill"; ' | npx esbuild --format=esm --target=es6 --bundle --minify
# Minify an ES5 build:
cat node_modules/clipboard-polyfill/dist/es5/window-var/clipboard-polyfill.window-var.promise.es5.js | npx esbuild --format=esm --target=es5 --bundle --minify
# Get a CommonJS build:
echo ' export * from "clipboard-polyfill"; ' | npx esbuild --format=cjs --target=es6 --bundle
clipboard-polyfill
?随着时间的推移,浏览器已经实现了多个剪贴板 API,并且在各种旧的和当前的浏览器中写入剪贴板而不触发错误是相当棘手的。在每个支持以某种方式复制到剪贴板的浏览器中, clipboard-polyfill
都会尝试尽可能接近异步剪贴板 API。 (有关免责声明和限制,请参阅上文。)
请参阅此演示文稿,了解网络上剪贴板访问的较长历史。
clipboard-polyfill
增加了支持。最早的浏览器版本写入支持:
浏览器 | writeText() | write() (HTML) | write() (其他格式) |
---|---|---|---|
Safari 13.1 | ☑️ | ☑️ | ☑️( image/uri-list , image/png ) |
Chrome 86 ᵃ /边缘 86 | ☑️ | ☑️ | ☑️( image/png ) |
Chrome 76ᵃ / 边缘 79 | ☑️ | ✅ | ☑️( image/png ) |
Chrome 66ᵃ / Firefox 63 | ☑️ | ✅ | |
Safari 10 / Chrome 42ᵃ / Edgeᵈ / Firefox 41 | ✅ | ✅ᵇ | |
浏览器9 | ✅ᶜ |
阅读支持:
浏览器 | readText() | read() (HTML) | read() (其他格式) |
---|---|---|---|
Safari 13.1 | ☑️ | ☑️ | ☑️( image/uri-list , image/png ) |
Chrome 76 ᵃ /边缘 79 | ☑️ | ☑️( image/png ) | |
Chrome 66ᵃ | ☑️ | ||
浏览器9 | ✅ᶜ | ||
火狐浏览器 |
window.Promise
。clipboard-polyfill
将始终报告成功。ClipboardItem
构造函数的对象的最后。text/html
数据类型未使用预期的CF_HTML
格式编写。 clipboard-polyfill
不会尝试解决此问题,因为 1) 它需要脆弱的浏览器版本嗅探,2) Edge 用户通常不会停留在版本 < 17 上,3) 其他浏览器的失败模式是无效的剪贴板HTML 已复制。 (边缘错误#14372529,#73) clipboard-polyfill
使用各种启发式方法来解决兼容性错误。如果您遇到与上面列出的任何浏览器的兼容性问题,请告诉我们。
浏览器 | 第一个版本支持navigator.clipboard.writeText(...) | 发布日期 |
---|---|---|
铬合金 | 66+ | 2018年4月 |
火狐浏览器 | 53+ | 2018年10月 |
边缘 | 79+(第一个基于 Chromium 的版本) | 2020年1月 |
狩猎之旅 | 13.1+ | 2020年3月 |
这个项目可以追溯到 JS 中的剪贴板访问几乎不可能实现的时代,而且符合人体工程学的剪贴板 API 工作也陷入停滞。 (有关更多背景信息,请参阅此演示文稿。)幸运的是,自 2020 年以来,具有相同功能的符合人体工程学的 API 现在可在所有现代浏览器中使用:
document.execCommand("copy")
调用(存在很多很多问题)。clipboard.js
形式启动这个项目(半年前 @zenorocha 选择了相同的名称?)。crbug.com/593475
)。clipboard-polyfill
以反映与草案规范一致的v2
API 改革。navigator.clipboard.writeText()
。navigator.clipboard.write()
(包括text/html
支持)。感谢 Gary Kacmarcik、Hallvord Steen 和其他人帮助将异步剪贴板 API 变为现实!
如果您只需要在现代浏览器中复制文本,请考虑直接使用navigator.clipboard.writeText()
:https://caniuse.com/mdn-api_clipboard_writetext
如果您还需要在旧版浏览器中复制文本,您也可以尝试这个要点以获得简单的解决方案。