Panoramica
Esistono tre API principali del browser per la copia negli Appunti:
- API Appunti asincroni
[navigator.clipboard.writeText]
- Parte focalizzata sul testo disponibile in Chrome 66 (marzo 2018)
- L'accesso è asincrono e utilizza promesse JavaScript , può essere scritto in modo che i prompt degli utenti di sicurezza (se visualizzati) non interrompano il JavaScript nella pagina.
- Il testo può essere copiato negli appunti direttamente da una variabile.
- Supportato solo su pagine pubblicate su HTTPS.
- In Chrome 66 pagine nelle schede attive possono scrivere negli Appunti senza una richiesta di autorizzazioni.
document.execCommand('copy')
- La maggior parte dei browser lo supporta a partire da ~ aprile 2015 (vedi Supporto browser di seguito).
- L'accesso è sincrono, ovvero interrompe JavaScript nella pagina fino al completamento, inclusa la visualizzazione e l'interazione dell'utente con qualsiasi richiesta di sicurezza.
- Il testo viene letto dal DOM e posizionato negli Appunti.
- Durante i test ~ aprile 2015, è stato notato che solo Internet Explorer visualizzava le richieste di autorizzazione durante la scrittura negli Appunti.
- Sostituzione dell'evento di copia
- Vedere la documentazione dell'API degli Appunti su Sostituzione dell'evento di copia .
- Consente di modificare ciò che appare negli Appunti da qualsiasi evento di copia, può includere altri formati di dati diversi dal testo normale.
- Non coperto qui in quanto non risponde direttamente alla domanda.
Note generali di sviluppo
Non aspettarti che i comandi relativi agli Appunti funzionino mentre stai testando il codice nella console. Generalmente la pagina deve essere attiva (API Appunti Asincrona) o richiede l'interazione dell'utente (ad es. Un clic dell'utente) per consentire ( document.execCommand('copy')
) di accedere agli Appunti, vedi sotto per maggiori dettagli.
IMPORTANTE (annotato qui 2020/02/20)
Si noti che poiché questo post è stato originariamente scritto deprecazione delle autorizzazioni negli IFRAME di origine incrociata e altri "sandboxing" IFRAME impediscono alle demo incorporate pulsanti "Esegui snippet di codice" e "esempio codepen.io" di funzionare in alcuni browser (inclusi Chrome e Microsoft Edge ).
Per sviluppare creare la propria pagina Web, servire quella pagina tramite la connessione HTTPS per testare e sviluppare.
Ecco una pagina di prova / demo che dimostra il funzionamento del codice:
https://deanmarktaylor.github.io/clipboard-test/
Async + Fallback
A causa del livello di supporto del browser per la nuova API Appunti di Async, sarà probabilmente necessario ricorrere al document.execCommand('copy')
metodo per ottenere una buona copertura del browser.
Ecco un semplice esempio (potrebbe non funzionare incorporato in questo sito, leggi la nota "importante" sopra):
function fallbackCopyTextToClipboard(text) {
var textArea = document.createElement("textarea");
textArea.value = text;
// Avoid scrolling to bottom
textArea.style.top = "0";
textArea.style.left = "0";
textArea.style.position = "fixed";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Fallback: Copying text command was ' + msg);
} catch (err) {
console.error('Fallback: Oops, unable to copy', err);
}
document.body.removeChild(textArea);
}
function copyTextToClipboard(text) {
if (!navigator.clipboard) {
fallbackCopyTextToClipboard(text);
return;
}
navigator.clipboard.writeText(text).then(function() {
console.log('Async: Copying to clipboard was successful!');
}, function(err) {
console.error('Async: Could not copy text: ', err);
});
}
var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
copyJaneBtn = document.querySelector('.js-copy-jane-btn');
copyBobBtn.addEventListener('click', function(event) {
copyTextToClipboard('Bob');
});
copyJaneBtn.addEventListener('click', function(event) {
copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
<button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
<button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
<textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:
</textarea>
</div>
(l'esempio codepen.io potrebbe non funzionare, leggi la nota "importante" sopra). Nota che questo frammento non funziona bene nell'anteprima incorporata di Stack Overflow, puoi provarlo qui: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors = 1011
API Appunti asincroni
Si noti che esiste la possibilità di "richiedere l'autorizzazione" e testare l'accesso agli Appunti tramite l'API delle autorizzazioni in Chrome 66.
var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
console.log('Async: Copying to clipboard was successful!');
}, function(err) {
console.error('Async: Could not copy text: ', err);
});
Document.ExecCommand ( 'copia')
Il resto di questo post esamina le sfumature e i dettagli document.execCommand('copy')
dell'API.
Supporto per il browser
Il document.execCommand('copy')
supporto JavaScript è cresciuto, vedere i collegamenti seguenti per gli aggiornamenti del browser:
Esempio semplice
(potrebbe non funzionare incorporato in questo sito, leggere la nota "importante" sopra)
var copyTextareaBtn = document.querySelector('.js-textareacopybtn');
copyTextareaBtn.addEventListener('click', function(event) {
var copyTextarea = document.querySelector('.js-copytextarea');
copyTextarea.focus();
copyTextarea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
} catch (err) {
console.log('Oops, unable to copy');
}
});
<p>
<button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
<textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>
Esempio complesso: copia negli appunti senza visualizzare input
Il semplice esempio sopra funziona alla grande se sullo schermo è visibile un elemento textarea
o input
.
In alcuni casi potresti voler copiare il testo negli Appunti senza visualizzare un elemento input
/ textarea
. Questo è un esempio di un modo per aggirare questo (fondamentalmente inserire elemento, copiare negli appunti, rimuovere elemento):
Testato con Google Chrome 44, Firefox 42.0a1 e Internet Explorer 11.0.8600.17814.
(potrebbe non funzionare incorporato in questo sito, leggere la nota "importante" sopra)
function copyTextToClipboard(text) {
var textArea = document.createElement("textarea");
//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a
// flash, so some of these are just precautions. However in
// Internet Explorer the element is visible whilst the popup
// box asking the user for permission for the web page to
// copy to the clipboard.
//
// Place in top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;
// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
// Avoid flash of white box if rendered for any reason.
textArea.style.background = 'transparent';
textArea.value = text;
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
} catch (err) {
console.log('Oops, unable to copy');
}
document.body.removeChild(textArea);
}
var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
copyJaneBtn = document.querySelector('.js-copy-jane-btn');
copyBobBtn.addEventListener('click', function(event) {
copyTextToClipboard('Bob');
});
copyJaneBtn.addEventListener('click', function(event) {
copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
<button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
<button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
<textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:
</textarea>
</div>
Note aggiuntive
Funziona solo se l'utente esegue un'azione
Tutte le document.execCommand('copy')
chiamate devono aver luogo come risultato diretto di un'azione dell'utente, ad es. Gestore di eventi click. Questa è una misura per evitare di scherzare con gli appunti dell'utente quando non se lo aspettano.
Vedi il post di Google Developers qui per maggiori informazioni.
API degli Appunti
Nota la specifica completa della bozza dell'API per Appunti è disponibile qui:
https://w3c.github.io/clipboard-apis/
È supportato?
document.queryCommandSupported('copy')
dovrebbe tornare true
se il comando "è supportato dal browser".
- e
document.queryCommandEnabled('copy')
restituire true
se l'operazione document.execCommand('copy')
avrà esito positivo se viene chiamata ora. Verifica per assicurarsi che il comando sia stato chiamato da un thread avviato dall'utente e che siano soddisfatti altri requisiti.
Tuttavia, come esempio di problemi di compatibilità del browser, Google Chrome da ~ aprile a ~ ottobre 2015 è tornato true
da solo document.queryCommandSupported('copy')
se il comando è stato chiamato da un thread avviato dall'utente.
Nota i dettagli di compatibilità di seguito.
Dettagli sulla compatibilità del browser
Mentre una semplice chiamata da document.execCommand('copy')
racchiudere in un blocco try
/ catch
chiamato come risultato di un clic dell'utente ti consentirà di utilizzare la massima compatibilità, alcune delle seguenti condizioni:
Qualsiasi chiamata a document.execCommand
, document.queryCommandSupported
o document.queryCommandEnabled
dovrebbe essere racchiusa in un blocco try
/ catch
.
Diverse implementazioni del browser e versioni del browser generano tipi diversi di eccezioni quando vengono chiamate anziché restituite false
.
Diverse implementazioni del browser sono ancora in evoluzione e l' API degli Appunti è ancora in bozza, quindi ricorda di fare i tuoi test.