clipboard-polyfill
clipboard-polyfill
para copiar texto! Nota: A partir de 2020, você pode usar navigator.clipboard.writeText(...)
nas versões estáveis de todos os principais navegadores. Esta biblioteca só será útil para você se você quiser:
text/html
no Firefox ≤126,ClipboardItem
no Firefox ≤126, oujsdom
).Consulte a seção Compatibilidade abaixo para obter mais detalhes.
Torna a cópia na web tão fácil quanto:
clipboard . writeText ( "hello world" ) ;
Esta biblioteca é um ponyfill/polyfill para a moderna API de área de transferência assíncrona baseada em Promise
.
Se você usar npm
, instale:
npm install clipboard-polyfill
Exemplo de aplicativo que copia texto para a área de transferência:
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 ) ;
} ) ;
Notas:
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 ) ;
} ) ;
Verifique a especificação da API da área de transferência para obter mais detalhes.
Notas:
async
para a sintaxe await
.text/plain
e text/html
são os únicos tipos de dados que podem ser gravados na área de transferência na maioria dos navegadores.read()
pode retornar apenas um subconjunto de tipos de dados suportados, mesmo que a área de transferência contenha mais tipos de dados. Não há como saber se havia mais tipos de dados.overwrite-globals
Se você deseja que a biblioteca substitua a API da área de transferência global por suas implementações, importe clipboard-polyfill/overwrite-globals
. Isso transformará a biblioteca de um ponyfill em um polyfill adequado, para que você possa escrever código como se a API assíncrona da área de transferência já estivesse implementada em seu navegador:
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 ) ;
} ) ;
Essa abordagem não é recomendada porque pode quebrar qualquer outro código que interaja com as APIs globais da área de transferência e pode ser incompatível com futuras implementações de navegador.
Promise
incluído Se você precisar obter uma versão que "simplesmente funcione", baixe clipboard-polyfill.window-var.promise.es5.js
e inclua-a usando uma tag <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 >
Graças às conveniências do ecossistema JS moderno, não fornecemos mais compilações tree shaken, minificadas ou CommonJS. Para obter essas compilações sem perder a compatibilidade, passe as compilações clipboard-polyfill
por meio de esbuild
. Por exemplo:
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
? Os navegadores implementaram várias APIs da área de transferência ao longo do tempo, e gravar na área de transferência sem desencadear bugs em vários navegadores antigos e atuais é bastante complicado. Em todos os navegadores que suportam de alguma forma a cópia para a área de transferência, clipboard-polyfill
tenta agir o mais próximo possível da API assíncrona da área de transferência. (Veja acima as isenções de responsabilidade e limitações.)
Veja esta apresentação para obter um histórico mais longo de acesso à área de transferência na web.
clipboard-polyfill
adiciona suporte.Suporte de gravação para a versão mais antiga do navegador:
Navegador | writeText() | write() (HTML) | write() (outros formatos) |
---|---|---|---|
Safári 13.1 | ☑️ | ☑️ | ☑️ ( image/uri-list , image/png ) |
Cromo 86ᵃ / Edge 86 | ☑️ | ☑️ | ☑️ ( image/png ) |
Cromo 76ᵃ / Borda 79 | ☑️ | ✅ | ☑️ ( image/png ) |
Chrome 66ᵃ / Firefox 63 | ☑️ | ✅ | |
Safari 10 / Chrome 42ᵃ / Edgeᵈ / Firefox 41 | ✅ | ✅ᵇ | |
Ou seja, 9 | ✅ᶜ |
Leia o suporte:
Navegador | readText() | read() (HTML) | read() (outros formatos) |
---|---|---|---|
Safári 13.1 | ☑️ | ☑️ | ☑️ ( image/uri-list , image/png ) |
Cromo 76ᵃ / Edge 79 | ☑️ | ☑️ ( image/png ) | |
Cromo 66ᵃ | ☑️ | ||
Ou seja, 9 | ✅ᶜ | ||
Raposa de fogo |
window.Promise
se quiser que a biblioteca funcione.clipboard-polyfill
sempre reportará sucesso neste caso.ClipboardItem
.text/html
não foi gravado usando o formato CF_HTML
esperado. clipboard-polyfill
não tenta contornar isso, pois 1) exigiria detecção de versão frágil do navegador, 2) os usuários do Edge geralmente não ficam presos na versão <17 e 3) o modo de falha para outros navegadores seria aquela área de transferência inválida HTML é copiado. (Bug de borda #14372529, #73) clipboard-polyfill
usa uma variedade de heurísticas para solucionar bugs de compatibilidade. Informe-nos se você estiver enfrentando problemas de compatibilidade com algum dos navegadores listados acima.
Navegador | Primeira versão com suportenavigator.clipboard.writeText(...) | Data de lançamento |
---|---|---|
Cromo | 66+ | Abril de 2018 |
Raposa de fogo | 53+ | Outubro de 2018 |
Borda | 79+ (primeira versão baseada em Chromium) | Janeiro de 2020 |
Safári | 13.1+ | Março de 2020 |
Este projeto data de uma época em que o acesso à área de transferência em JS mal se tornava possível e os esforços ergonômicos da API da área de transferência estavam estagnados. (Veja esta apresentação para um pouco mais de contexto.) Felizmente, uma API ergonômica com a mesma funcionalidade está agora disponível em todos os navegadores modernos desde 2020:
document.execCommand("copy")
(com muitos, muitos problemas).clipboard.js
(meio ano antes de @zenorocha escolher o mesmo nome?).crbug.com/593475
).clipboard-polyfill
para refletir uma revisão da API v2
alinhada com o rascunho das especificações.navigator.clipboard.writeText()
.navigator.clipboard.write()
(incluindo suporte text/html
).Obrigado a Gary Kacmarcik, Hallvord Steen e outros por ajudarem a dar vida à API assíncrona da área de transferência!
Se você só precisa copiar texto em navegadores modernos, considere usar navigator.clipboard.writeText()
diretamente: https://caniuse.com/mdn-api_clipboard_writetext
Se você também precisar copiar texto em navegadores mais antigos, você também pode tentar esta essência para uma solução hacky simples.