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
如果您還需要在舊版瀏覽器中複製文本,您也可以嘗試此要點以獲得簡單的解決方案。