2015-08-10 16 views
5

(testati utilizzando Chrome 44)execCommand ('copia') non funziona nel callback Ajax/XHR?

desiderata comportamento: Fai la richiesta XHR, messo risultato nella zona di testo, selezionare il testo e copiarlo negli appunti.

Comportamento effettivo: in caso di richiesta XHR corretta, inserisce il risultato nell'area di testo e lo seleziona, ma non riesce a copiare il risultato negli Appunti. Ma se avvio la copia al di fuori del callback XHR, funziona.

Esempio pagina html:

var selectAndCopy = function() { 
 
    // Select text 
 
    var cutTextarea = document.querySelector('#textarea'); 
 
    cutTextarea.select(); 
 
    // Execute copy 
 
    var successful = document.execCommand('copy'); 
 
    var msg = successful ? 'successful' : 'unsuccessful'; 
 
    console.log('Cutting text command was ' + msg); 
 
}; 
 

 
var fetchCopyButton = document.querySelector('#fetch_copy'); 
 
fetchCopyButton.addEventListener('click', function(event) { 
 
    var xhr = new XMLHttpRequest(); 
 
    xhr.open('get', 'http://httpbin.org/ip'); 
 
    xhr.onreadystatechange = function() { 
 
    if (xhr.readyState === 4) { 
 
     if (xhr.status === 200) { 
 
     // Set text 
 
     var textarea = document.querySelector('#textarea'); 
 
     textarea.value = xhr.responseText; 
 

 
     selectAndCopy(); 
 
     } 
 
    } 
 
    }; 
 
    xhr.send(); 
 
}); 
 

 
var copyButton = document.querySelector('#copy'); 
 
copyButton.addEventListener('click', function(event) { 
 
    selectAndCopy(); 
 
});
<html> 
 

 
<head> 
 
</head> 
 

 
<body> 
 
    <p> 
 
    <textarea id="textarea">Hello, I'm some text!</textarea> 
 
    </p> 
 
    <p> 
 
    <button id="fetch_copy">Fetch Data and Copy Textarea</button> 
 
    <button id="copy">Copy Textarea</button> 
 
    </p> 
 
</body> 
 

 
</html>

Se si preme il pulsante "recuperare i dati e Copia Textarea" i dati vengono scaricati con successo, ma non copiato. Se si preme il pulsante "Copia area di testo", il testo viene copiato come previsto. Ho provato molte combinazioni di richiesta/copia per provare a farlo funzionare ma senza alcun risultato (inclusa la pressione programmatica del pulsante di copia dopo aver recuperato i dati). Qualcuno sa cosa sta succedendo qui? È una caratteristica di sicurezza o qualcosa del genere?

Non voglio che l'utente debba premere due pulsanti per recuperare e copiare se possibile.

+0

Quindi, come avete risolto, alla fine? Potresti aggiornare la domanda? – ChrisGeo

+0

@ChrisGeo Ho finito per selezionare il testo (ma non copiarlo). Mi sono reso conto che probabilmente gli utenti non sarebbero felici se avessi sovrascritto qualcosa nel loro buffer di copia. La risposta di Trevor sotto sembra funzionare (se si sta bene con XHR sincrono) – aeoliant

+0

Questo problema è risolto in my ans :) qui: http://stackoverflow.com/questions/43380921/not-able-to-copy -a-link-direttamente-when-i-am-using-ajax/43381458 # 43381458 –

risposta

12

È possibile attivare una copia negli Appunti di sistema solo in risposta diretta a un'azione dell'utente affidabile, ad esempio un evento click.

Spec: http://www.w3.org/TR/clipboard-apis/#integration-with-rich-text-editing-apis

+0

grazie! (accetterà il prima possibile) – aeoliant

+0

Grazie @Tim Down. Finalmente ho trovato la tua risposta –

+0

Ho risolto questo problema qui :) http://stackoverflow.com/questions/43380921/not-able-to-copy-a-link-directly-when-i-am-using- ajax/43381458 # 43381458 –

7

Se si effettua la XMLHttpRequest sincrono, questo funzionerà. Non vi resta che aggiungere false come terzo parametro per xhr.open(...):

var selectAndCopy = function() { 
 
    // Select text 
 
    var cutTextarea = document.querySelector('#textarea'); 
 
    cutTextarea.select(); 
 
    // Execute copy 
 
    var successful = document.execCommand('copy'); 
 
    var msg = successful ? 'successful' : 'unsuccessful'; 
 
    console.log('Cutting text command was ' + msg); 
 
}; 
 

 
var fetchCopyButton = document.querySelector('#fetch_copy'); 
 
fetchCopyButton.addEventListener('click', function(event) { 
 
    var xhr = new XMLHttpRequest(); 
 
    xhr.open('get', 'http://httpbin.org/ip', false); 
 
    xhr.onreadystatechange = function() { 
 
    if (xhr.readyState === 4) { 
 
     if (xhr.status === 200) { 
 
     // Set text 
 
     var textarea = document.querySelector('#textarea'); 
 
     textarea.value = xhr.responseText; 
 

 
     selectAndCopy(); 
 
     } 
 
    } 
 
    }; 
 
    xhr.send(); 
 
}); 
 

 
var copyButton = document.querySelector('#copy'); 
 
copyButton.addEventListener('click', function(event) { 
 
    selectAndCopy(); 
 
});
<html> 
 

 
<head> 
 
</head> 
 

 
<body> 
 
    <p> 
 
    <textarea id="textarea">Hello, I'm some text!</textarea> 
 
    </p> 
 
    <p> 
 
    <button id="fetch_copy">Fetch Data and Copy Textarea</button> 
 
    <button id="copy">Copy Textarea</button> 
 
    </p> 
 
</body> 
 

 
</html>

+1

XHR sincrono è generalmente una cattiva idea, ma è difficile vedere un modo per farlo in un solo passaggio senza di esso. Inoltre, riceverai avvisi relativi alle richieste XHR sincrone nella console di Chrome. –

Problemi correlati