Copier vers le presse-papier du système d'exploitation une information provenant du document est une tâche que l'on souhaite parfois réaliser pour faciliter la vie de l'utilisateur, lors de l'utilisation d'une application web : une chaîne aléatoire complexe, une URL, une clé, ou tout simplement un message... C'est à la portée de la fonction JavaScript execCommand()
qui prend en paramètre l'opération que l'on souhaite réaliser copy
(copier), cut
(couper), paste
(coller).
On retrouve ce principe souvent sur les fonctions de partage de document par lien tel que sur Google Drive :
Ceci fait l'objet d'une spécification "non officielle" execCommand pourtant très bien supportée par tous les navigateurs. A terme, on devrait plutôt s'orienter vers ContentEditable et Input Events
Supposons que vous avez structuré le texte à copier de la façon suivante, dans un quelconque élément HTML :
<p>
Copiez cette adresse : <span id="tocopy">https://www.knacss.com/</span>
</p>
On va y adjoindre un bouton d'action pour lancer la copie, doté d'une classe js-copy
pour lui lier un événement JavaScript et un attribut data-target
permettant de ne pas coder "en dur" dans la fonction correspondante l'élément cible. Ceci a l'intérêt de pouvoir réutiliser cette même classe js-copy
avec de multiples éléments, chacun définissant quelle est sa "source" d'information.
<p>
Copiez cette adresse : <span id="tocopy">https://www.knacss.com/</span>
<input type="button" value="Copier" class="js-copy" data-target="#tocopy">
</p>
Sans plus attendre, le script associé, qui va se servir des méthodes createRange
et getSelection
pour sélectionner une portion de contenu dans le document et ensuite exécuter par-dessus la commande de copie :
var btncopy = document.querySelector('.js-copy');
if(btncopy) {
btncopy.addEventListener('click', docopy);
}
function docopy() {
// Cible de l'élément qui doit être copié
var target = this.dataset.target;
var fromElement = document.querySelector(target);
if(!fromElement) return;
// Sélection des caractères concernés
var range = document.createRange();
var selection = window.getSelection();
range.selectNode(fromElement);
selection.removeAllRanges();
selection.addRange(range);
try {
// Exécution de la commande de copie
var result = document.execCommand('copy');
if (result) {
// La copie a réussi
alert('Copié !');
}
}
catch(err) {
// Une erreur est surevnue lors de la tentative de copie
alert(err);
}
// Fin de l'opération
selection = window.getSelection();
if (typeof selection.removeRange === 'function') {
selection.removeRange(range);
} else if (typeof selection.removeAllRanges === 'function') {
selection.removeAllRanges();
}
}
Démo
See the Pen Copier by Alsacreations (@alsacreations) on CodePen.
Pour savoir si une commande est supportée par le navigateur, on peut interroger la méthode queryCommandSupported
en lui passant en paramètre le nom de la commande :
document.queryCommandSupported('copy')
Commentaires
Je trouve que l'article aurait pu être plus poussé. Qu'en est-il de l'API Clipboard ?
Sinon, pourquoi ne pas avoir utilisé la fonction select comme ceci : `document.querySelector(target).select();` qui, pour moi, facilite bien plus la tâche et économise plusieurs lignes de code pour ce qui est de copier le texte. Le code allégé deviendrait ainsi :
```js
const btncopy = document.querySelector('.js-copy');
if (btncopy !== null) {
btncopy.addEventListener('click', docopy);
}
function docopy() {
const fromElement = document.querySelector(this.dataset.target);
if (fromElement === null) {
return false;
}
fromElement.select();
try {
const result = document.execCommand('copy');
if (result) {
alert('Copié !');
}
} catch (err) {
// Une erreur est survenue lors de la tentative de copie
alert(err);
}
}
```
@-Propre : La méthode select marche uniquement sur des <textarea> ou des <input>. Il ne marcherait pas sur l’exemple donné qui utilise des <div>.
@-Propre : La méthode select marche uniquement sur des <textarea> ou des <input>. Il ne marcherait pas sur l’exemple donné qui utilise des <div>.
Petit déterrage d'automne :)
Tuto très utile, perso j'utilise execCommand dans une fonction spécialisée qui va se charger de copier une chaine passée en paramètre.
Donc sur le même principe mais avec l'utilisation d'un 'textarea' temporaire:
[code=javascript]
// appel de fonction pour copier une chaine quelconque
copyToClipboard('785689745581398752302573082536497');
const copyToClipboard = function (str) {
const tempArea = document.createElement('textarea');
tempArea.value = str;
document.body.appendChild(tempArea);
tempArea.select();
document.execCommand('copy');
document.body.removeChild(tempArea);
};
[/code]
Bonjour, je trouve l'explication très bien pour un néophyte comme moi. Je n'arrive pas à mettre en place dans un formulaire la fonction coller. j'explique je souhaite récupérer le contenu du presse papier et le coller dans un champ text d'un formulaire sur l'évènement OnClick d'un bouton. Je pense que c'est possible.
Pouvez vous éclairer ma lanterne.
Merci d'avance
Bonjour,
J'ai "récupéré" cette astuce pour mon site. Elle marche, mais pas comme espéré.
J'ai plusieurs boutons identiques sur une page pour copier des champs différents, mais seul le premier fonctionne, rien ne se passe sur les autres.
Comment faire pour que tous fonctionnent ?
Je précise ne pas connaître le javascript.
Merci par avance pour votre réponse.
Salutations.
Bonjour,
J'ai "récupéré" cette astuce pour mon site. Elle marche, mais pas comme espéré.
J'ai plusieurs boutons identiques sur une page pour copier des champs différents, mais seul le premier fonctionne, rien ne se passe sur les autres.
Comment faire pour que tous fonctionnent ?
Je précise ne pas connaître le javascript.
Merci par avance pour votre réponse.
Salutations.
Bonjour,
Pour compléter la question ci-dessus, j'ai pris le code source de cette page où l'on est actuellement et j'ai doublé la partie démo :
<h3>Démo</h3>
<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="alsacreations" data-slug-hash="rbEpqM" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="Copier">
<span>See the Pen <a href="https://codepen.io/alsacreations/pen/rbEpqM/">
Copier</a> by Alsacreations (<a href="https://codepen.io/alsacreations">@alsacreations</a>)
on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
À l'exécution, le même phénomène que dans ma page se produit : seul le premier clic sur "Copier" fonctionne !
Salutations.
Bonjour,
J'ai "récupéré" cette astuce pour mon site. Elle marche, mais pas comme espéré.
J'ai plusieurs boutons identiques sur une page pour copier des champs différents, mais seul le premier fonctionne, rien ne se passe sur les autres.
Comment faire pour que tous fonctionnent ?
Je précise ne pas connaître le javascript.
Merci par avance pour votre réponse.
Salutations.