Domanda Come posso copiare negli appunti in JavaScript?


Qual è il modo migliore per copiare il testo negli appunti? (Multi-browser)

Ho provato:

function copyToClipboard(text) {
    if (window.clipboardData) { // Internet Explorer
        window.clipboardData.setData("Text", text);
    } else {  
        unsafeWindow.netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  
        const clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);  
        clipboardHelper.copyString(text);
    }
}

ma in Internet Explorer dà un errore di sintassi. In Firefox, dice unsafeWindow is not defined.

Un bel trucco senza flash: In che modo Trello accede agli appunti dell'utente?


2662
2017-12-30 13:09


origine


risposte:


Panoramica

Esistono 3 API principali del browser per la copia negli Appunti:

  1. API Async Clipboard  [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 dell'utente di sicurezza (se visualizzati) non interrompano il JavaScript nella pagina.
    • Il testo può essere copiato negli Appunti direttamente da una variabile.
    • Supportato solo sulle pagine pubblicate su HTTPS.
    • In Chrome 66 pagine in schede attive possono scrivere negli appunti senza una richiesta di autorizzazione.
  2. document.execCommand('copy')
    • La maggior parte dei browser lo supporta a partire da ~ aprile 2015 (vedi Supporto per browser sotto).
    • L'accesso è sincrono, ovvero arresta 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 inserito negli Appunti.
    • Durante i test ~ aprile 2015 è stato notato solo Internet Explorer che visualizza i prompt delle autorizzazioni durante la scrittura negli Appunti.
  3. Override dell'evento di copia
    • Vedere la documentazione dell'API degli appunti su Override dell'evento di copia.
    • Permette di modificare ciò che appare negli appunti da qualsiasi evento di copia, può includere altri formati di dati diversi dal semplice testo.
    • Non coperto qui in quanto non risponde direttamente alla domanda.

Note generali di sviluppo

Non aspettarti che i comandi relativi agli Appunti funzionino mentre esegui il test del codice nella console. Generalmente la pagina deve essere attiva (Async Clipboard API) o richiede l'interazione dell'utente (ad esempio un clic dell'utente) per consentire (document.execCommand('copy')) per accedere agli appunti vedi sotto per maggiori dettagli.

Async + Fallback

A causa del livello di supporto del browser per la nuova API Async Clipboard, è probabile che si desideri eseguire il fallback document.execCommand('copy') metodo per ottenere una buona copertura del browser.

Qui c'è un semplice esempio:

function fallbackCopyTextToClipboard(text) {
  var textArea = document.createElement("textarea");
  textArea.value = text;
  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>

Nota che questo frammento non funziona bene nell'anteprima integrata di StackOverflow puoi provarlo qui: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors=1011

API Async Clipboard

Tieni presente che esiste la possibilità di "richiedere l'autorizzazione" e testare l'accesso agli Appunti tramite l'API di autorizzazione 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 va nelle sfumature e nei dettagli del document.execCommand('copy') API.

Supporto del browser

Il JavaScript document.execCommand('copy') il supporto è cresciuto, vedi i collegamenti sottostanti per gli aggiornamenti del browser:

Semplice esempio

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

L'esempio semplice sopra funziona alla grande se c'è un textarea o input elemento visibile sullo schermo.

In alcuni casi potresti voler copiare il testo negli Appunti senza visualizzare un input / textarea elemento. Questo è un esempio di come aggirare questo problema (in pratica inserire elemento, copiare negli appunti, rimuovere elemento):

Testato con Google Chrome 44, Firefox 42.0a1 e IE 11.0.8600.17814.

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 IE 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 intraprende un'azione

Tutti document.execCommand('copy') le chiamate devono avvenire come risultato diretto di un'azione dell'utente, ad es. fare clic su gestore di eventi. Questa è una misura per evitare di incasinare gli appunti degli utenti quando non se lo aspettano.

Vedere il Google Developers postare qui per maggiori informazioni.

API degli appunti

Si noti che la specifica completa della bozza dell'API di Clipboard può essere trovata qui: https://w3c.github.io/clipboard-apis/

È supportato?

  • document.queryCommandSupported('copy') dovrebbe tornare true se il comando "è supportato dal browser".
  • e document.queryCommandEnabled('copy') ritorno true se la document.execCommand('copy') riuscirà se chiamato ora. Verifica che il comando sia stato richiamato 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 è stato restituito true a partire dal document.queryCommandSupported('copy') se il comando è stato chiamato da un thread avviato dall'utente.

Notare i dettagli sulla compatibilità di seguito.

Dettaglio di compatibilità del browser

Mentre una semplice chiamata a document.execCommand('copy') avvolto in a try/catch il blocco richiamato come risultato di un clic dell'utente ti consente di ottenere la massima compatibilità. Di seguito sono riportate alcune condizioni:

Qualsiasi chiamata a document.execCommand, document.queryCommandSupported o document.queryCommandEnabled dovrebbe essere avvolto in a try/catch bloccare.

Diverse implementazioni del browser e versioni del browser generano diversi tipi di eccezioni quando vengono richiamati anziché restituiti false.

Diverse implementazioni del browser sono ancora in evoluzione e il API degli appunti è ancora in fase di bozza, quindi ricorda di fare i test.


1581
2018-06-12 18:56



La copia automatica negli appunti può essere pericolosa, quindi la maggior parte dei browser (tranne IE) lo rende molto difficile. Personalmente, io uso il seguente semplice trucco:

function copyToClipboard(text) {
  window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
}

L'utente viene presentato con la casella di richiesta, in cui il testo da copiare è già selezionato. Adesso basta premere Ctrl+C e accedere (per chiudere la scatola) - e voilà!

Ora l'operazione di copia degli appunti è SICURA, perché l'utente lo fa manualmente (ma in un modo piuttosto diretto). Certo, funziona su tutti i browser.

<button id="demo" onclick="copyToClipboard(document.getElementById('demo').innerHTML)">This is what I want to copy</button>

<script>
  function copyToClipboard(text) {
    window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
</script>


1194
2018-05-19 08:06



Il seguente approccio funziona in Chrome, Firefox, Internet Explorer e Edge e nelle versioni recenti di Safari (il supporto per la copia è stato aggiunto nella versione 10, che è stata rilasciata nell'ottobre 2016).

  • Crea una textarea e imposta il suo contenuto sul testo che vuoi copiare negli appunti.
  • Aggiungi la textarea al DOM.
  • Seleziona il testo nella textarea.
  • Chiama document.execCommand ("copia")
  • Rimuovi la textarea dal dom.

Nota: non vedrai la textarea, poiché viene aggiunta e rimossa all'interno della stessa invocazione sincrona del codice Javascript.

Alcune cose a cui prestare attenzione se la stai implementando da sola:

  • Per motivi di sicurezza, questo può essere chiamato solo da un gestore di eventi come click (Proprio come con le finestre di apertura).
  • IE mostrerà una finestra di dialogo di autorizzazione la prima volta che gli appunti vengono aggiornati.
  • IE e Edge scorreranno quando la textarea è focalizzata.
  • execCommand () può lanciare in alcuni casi.
  • Newlines e tab possono essere ingoiati a meno che non si usi una textarea. (La maggior parte degli articoli sembra raccomandare l'uso di un div)
  • La textarea sarà visibile mentre viene mostrata la finestra di dialogo di IE, è necessario nasconderla o utilizzare l'API di appunti specifica di IE.
  • In IE gli amministratori di sistema possono disabilitare l'API degli Appunti.

La funzione seguente dovrebbe gestire tutti i seguenti problemi nel modo più pulito possibile. Si prega di lasciare un commento se si riscontrano problemi o suggerimenti per migliorarlo.

// Copies a string to the clipboard. Must be called from within an 
// event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+, 
// Firefox 42+, Safari 10+, Edge and IE 10+.
// IE: The clipboard feature may be disabled by an administrator. By
// default a prompt is shown the first time the clipboard is 
// used (per session).
function copyToClipboard(text) {
    if (window.clipboardData && window.clipboardData.setData) {
        // IE specific code path to prevent textarea being shown while dialog is visible.
        return clipboardData.setData("Text", text); 

    } else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
        var textarea = document.createElement("textarea");
        textarea.textContent = text;
        textarea.style.position = "fixed";  // Prevent scrolling to bottom of page in MS Edge.
        document.body.appendChild(textarea);
        textarea.select();
        try {
            return document.execCommand("copy");  // Security exception may be thrown by some browsers.
        } catch (ex) {
            console.warn("Copy to clipboard failed.", ex);
            return false;
        } finally {
            document.body.removeChild(textarea);
        }
    }
}

https://jsfiddle.net/fx6a6n6x/


194
2017-11-26 00:03



Se vuoi una soluzione davvero semplice (richiede meno di 5 minuti per l'integrazione) e sembra subito pronta, allora Clippy è una buona alternativa ad alcune delle soluzioni più complesse.

Clippy

È stato scritto da un co-fondatore di Github. Esempio di codice di incorporamento Flash di seguito:

<object 
   classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
   width="110"
   height="14"
   id="clippy">
  <param name="movie" value="/flash/clippy.swf"/>
  <param name="allowScriptAccess" value="always"/>
  <param name="quality" value="high"/>
  <param name="scale" value="noscale"/>
  <param NAME="FlashVars" value="text=#{text}"/>
  <param name="bgcolor" value="#{bgcolor}"/>
  <embed 
     src="/flash/clippy.swf"
     width="110"
     height="14"
     name="clippy"
     quality="high"
     allowScriptAccess="always"
     type="application/x-shockwave-flash"
     pluginspage="http://www.macromedia.com/go/getflashplayer"
     FlashVars="text=#{text}"
     bgcolor="#{bgcolor}"/>
</object>

Ricordarsi di sostituire #{text} con il testo che devi copiare, e #{bgcolor} con un colore.


93
2017-10-17 14:40



Leggere e modificare gli appunti da una pagina Web solleva problemi di sicurezza e privacy. Tuttavia, in Internet Explorer, è possibile farlo. ho trovato questo esempio di snippet:

    <script type="text/javascript">
        function select_all(obj) {
            var text_val=eval(obj);
            text_val.focus();
            text_val.select();
            r = text_val.createTextRange();
            if (!r.execCommand) return; // feature detection
            r.execCommand('copy');
        }
    </script>
    <input value="http://www.sajithmr.com"
     onclick="select_all(this)" name="url" type="text" />


77
2017-12-30 13:33



Ho recentemente scritto a post del blog tecnico proprio su questo problema (lavoro con Lucidchart e recentemente abbiamo fatto una revisione dei nostri appunti).

Copiare testo semplice negli appunti è relativamente semplice, assumendo che si desideri farlo durante un evento di copia del sistema (l'utente preme CtrlC o usa il menu del browser).

var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 
           || navigator.userAgent.toLowerCase().indexOf("trident") != -1);

document.addEventListener('copy', function(e) {
    var textToPutOnClipboard = "This is some text";
    if (isIe) {
        window.clipboardData.setData('Text', textToPutOnClipboard);    
    } else {
        e.clipboardData.setData('text/plain', textToPutOnClipboard);
    }
    e.preventDefault();
});

Mettere il testo negli Appunti non durante un evento di copia di sistema è molto più difficile. Sembra che alcune di queste altre risposte facciano riferimento a come farlo tramite Flash, che è l'unico modo per farlo da browser (per quanto ho capito).

Oltre a questo, ci sono alcune opzioni su una base browser per browser.

Questo è il più semplice in IE, in cui è possibile accedere all'oggetto ClipboardData in qualsiasi momento da JavaScript tramite:

window.clipboardData

(Quando si tenta di eseguire ciò al di fuori di un evento di taglio, copia o incolla del sistema, tuttavia, IE richiederà all'utente di concedere l'autorizzazione per gli Appunti dell'applicazione Web.)

In Chrome, puoi creare un'estensione per Chrome che ti darà autorizzazioni per gli appunti (questo è ciò che facciamo per Lucidchart). Quindi per gli utenti con la tua estensione installata dovrai solo attivare l'evento di sistema da solo:

document.execCommand('copy');

Sembra che Firefox abbia alcune opzioni che consente agli utenti di concedere autorizzazioni ad alcuni siti per accedere agli appunti, ma non ho provato nessuno di questi personalmente.


65
2017-12-03 20:31



clipboard.js è una piccola utility non flash che consente di copiare testo o dati html negli appunti. È molto facile da usare, basta includere .js e usare qualcosa del genere:

<button id='markup-copy'>Copy Button</button>

<script>
document.getElementById('markup-copy').addEventListener('click', function() {
  clipboard.copy({
    'text/plain': 'Markup text. Paste me into a rich text editor.',
    'text/html': '<i>here</i> is some <b>rich text</b>'
  }).then(
    function(){console.log('success'); },
    function(err){console.log('failure', err);
  });

});
</script>

anche clipboard.js è attivo GitHub


44
2017-08-11 15:33



ZeroClipboard è la migliore soluzione cross-browser che ho trovato:

<div id="copy" data-clipboard-text="Copy Me!">Click to copy</div>    
<script src="ZeroClipboard.js"></script>
<script>
  var clip = new ZeroClipboard( document.getElementById('copy') );
</script>

Se hai bisogno di supporto non flash per iOS, devi solo aggiungere un fallback:

clip.on( 'noflash', function ( client, args ) {
    $("#copy").click(function(){            
        var txt = $(this).attr('data-clipboard-text');
        prompt ("Copy link, then click OK.", txt);
    });
});  

http://zeroclipboard.org/

https://github.com/zeroclipboard/ZeroClipboard


35
2017-11-21 20:41



Ecco la mia versione di quello ..

function copy(text) {
    var input = document.createElement('input');
    input.setAttribute('value', text);
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input)
    return result;
 }

29
2017-09-14 09:20