Copie au bloc-notes en utilisant Javascript dans iOS
j'utilise cette fonction pour copier une URL vers le presse-papiers:
function CopyUrl($this){
var querySelector = $this.next().attr("id");
var emailLink = document.querySelector("#"+querySelector);
var range = document.createRange();
range.selectNode(emailLink);
window.getSelection().addRange(range);
try {
// Now that we've selected the anchor text, execute the copy command
var successful = document.execCommand('copy', false, null);
var msg = successful ? 'successful' : 'unsuccessful';
if(true){
$this.addClass("copied").html("Copied");
}
} catch(err) {
console.log('Oops, unable to copy');
}
// Remove the selections - NOTE: Should use
// removeRange(range) when it is supported
window.getSelection().removeAllRanges();
}
Tout fonctionne bien sur les navigateurs de bureau, mais pas sur les appareils iOS, où ma fonction retourne avec succès, mais les données ne sont pas du tout copiées dans le presse-papiers. Quelle est la cause et comment pourrais-je résoudre ce problème?
5 réponses
mise à jour! iOS > = 10
ressemble avec l'aide des gammes de sélection et un peu de hack il est possible de copier directement au presse-papiers sur iOS (>= 10) Safari. J'ai personnellement testé sur iPhone 5C iOS 10.3.3 et iPhone 8 iOS 11.1. Cependant, il semble y avoir certaines restrictions, qui sont:
- le texte ne peut être copié qu'à partir des éléments
<input>
et<textarea>
. - si l'élément le texte est pas à l'intérieur d'un
<form>
, alors il doit êtrecontenteditable
. - l'élément contenant le texte doit et non être
readonly
(bien que vous puissiez essayer, ce n'est pas une méthode" officielle " documentée n'importe où). - Le texte à l'intérieur de l'élément doit être dans la plage de sélection.
pour couvrir ces quatre "exigences", vous devrez::
- placez le texte à copier dans un élément
<input>
ou<textarea>
. - sauvegarder les anciennes valeurs de
contenteditable
etreadonly
de l'élément pour pouvoir les restaurer après copie. - changer
contenteditable
entrue
etreadonly
enfalse
. - Créer un gamme pour sélectionner l'élément souhaité et l'ajouter à la fenêtre sélection.
- définit la gamme de sélection" 1519600920 pour l'ensemble de l'élément.
- restaurer les valeurs précédentes
contenteditable
etreadonly
. - Exécuter
execCommand('copy')
.
cela provoquera le caret de l'appareil de l'utilisateur de se déplacer et de sélectionner tout le texte dans l'élément que vous voulez, puis automatiquement émettre la commande de copie. De l'utilisateur le texte sélectionné et le outil de pointe avec les options sélectionner/copier/coller sera montré.
maintenant, cela semble un peu compliqué et trop de tracas pour juste émettre une commande de copie, donc je ne suis pas sûr que ce soit un choix de conception prévu par Apple, mais qui sait... entre - temps, ce fonctionne actuellement sur iOS >= 10 .
avec ceci dit, les polyfills comme celui-ci pourrait être utilisé pour simplifier cette action et faire croix-navigateur compatible (merci @Toskan pour le lien dans les commentaires).
exemple pratique
pour résumer, le code dont vous aurez besoin ressemble à ceci:
function iosCopyToClipboard(el) {
var oldContentEditable = el.contentEditable,
oldReadOnly = el.readOnly,
range = document.createRange();
el.contentEditable = true;
el.readOnly = false;
range.selectNodeContents(el);
var s = window.getSelection();
s.removeAllRanges();
s.addRange(range);
el.setSelectionRange(0, 999999); // A big number, to cover anything that could be inside the element.
el.contentEditable = oldContentEditable;
el.readOnly = oldReadOnly;
document.execCommand('copy');
}
notez que le paramètre el
de cette fonction doit être un <input>
ou un <textarea>
.
ancienne réponse: versions précédentes de iOS
sur iOS < 10 il y a quelques restrictions pour Safari (qui sont en réalité des mesures de sécurité), à la presse-papiers de l'API :
- feux
copy
événements uniquement sur une sélection valide etcut
etpaste
seulement des champs modifiables. - it only supports OS presse-papiers lecture/écriture via les touches de raccourci, et non par
document.execCommand()
. noter que par "touche de raccourci", on entend une touche cliquable (par exemple, menu d'action copier/coller ou raccourci clavier iOS personnalisé) ou physique (par exemple, clavier bluetooth connecté). - il ne supporte pas le constructeur
ClipboardEvent
.
donc (au moins à partir de maintenant) il n'est pas possible de copier programmatiquement du texte ou de la valeur dans le presse-papiers sur un périphérique iOS en utilisant Javascript . Seul l'utilisateur peut décider de copier quelque chose.
il est cependant possible de sélectionner quelque chose par programme , de sorte que l'utilisateur n'a qu'à cliquer sur le bout d'outil "Copier" affiché sur la sélection. Cela peut être réalisé avec le même code que ci-dessus, en enlevant simplement le execCommand('copy')
, qui ne va pas fonctionner.
j'ai cherché des solutions et j'en ai trouvé une qui fonctionne vraiment: http://www.seabreezecomputers.com/tips/copy2clipboard.htm
en gros, exemple pourrait être quelque chose comme:
var $input = $(' some input/textarea ');
$input.val(result);
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
var el = $input.get(0);
var editable = el.contentEditable;
var readOnly = el.readOnly;
el.contentEditable = true;
el.readOnly = false;
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
el.setSelectionRange(0, 999999);
el.contentEditable = editable;
el.readOnly = readOnly;
} else {
$input.select();
}
document.execCommand('copy');
$input.blur();
pour des raisons de sécurité, iOS Safari n'autorise document.execCommand('copy')
que pour le texte à l'intérieur d'un conteneur contentEditable
.
la solution est de détecter iOS Safari et de basculer rapidement contentEditable
avant d'exécuter document.execCommand('copy')
.
la fonction suivante doit fonctionner dans tous les navigateurs / dispositifs et accepte un sélecteur CSS ou HTMLElement :
function copyToClipboard(el) {
// resolve the element
el = (typeof el === 'string') ? document.querySelector(el) : el;
// handle iOS as a special case
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
// save current contentEditable/readOnly status
var editable = el.contentEditable;
var readOnly = el.readOnly;
// convert to editable with readonly to stop iOS keyboard opening
el.contentEditable = true;
el.readOnly = true;
// create a selectable range
var range = document.createRange();
range.selectNodeContents(el);
// select the range
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
el.setSelectionRange(0, 999999);
// restore contentEditable/readOnly to original state
el.contentEditable = editable;
el.readOnly = readOnly;
}
else {
el.select();
}
// execute copy command
document.execCommand('copy');
}
input { font-size: 14px; font-family: tahoma; }
button { font-size: 14px; font-family: tahoma; }
<input class="important-message" type="text" value="Hello World" />
<button onclick="copyToClipboard('.important-message')">Copy</button>
Vérifiez ma solution.
il fonctionne sur Safari (testé sur iPhone 7 et iPad) et sur d'autres navigateurs.
window.Clipboard = (function(window, document, navigator) {
var textArea,
copy;
function isOS() {
return navigator.userAgent.match(/ipad|iphone/i);
}
function createTextArea(text) {
textArea = document.createElement('textArea');
textArea.value = text;
document.body.appendChild(textArea);
}
function selectText() {
var range,
selection;
if (isOS()) {
range = document.createRange();
range.selectNodeContents(textArea);
selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
textArea.setSelectionRange(0, 999999);
} else {
textArea.select();
}
}
function copyToClipboard() {
document.execCommand('copy');
document.body.removeChild(textArea);
}
copy = function(text) {
createTextArea(text);
selectText();
copyToClipboard();
};
return {
copy: copy
};
})(window, document, navigator);
// How to use
Clipboard.copy('text to be copied');
https://gist.github.com/rproenca/64781c6a1329b48a455b645d361a9aa3 https://fiddle.jshell.net/k9ejqmqt/1 /
Espère que vous aide.
Cordialement.
<input id="copyIos" type="hidden" value="">
var clipboard = new Clipboard('.copyUrl');
//兼容ios复制
$('.copyUrl').on('click',function() {
var $input = $('#copyIos');
$input.val(share_url);
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
clipboard.on('success', function(e) {
e.clearSelection();
$.sDialog({
skin: "red",
content: 'copy success!',
okBtn: false,
cancelBtn: false,
lock: true
});
console.log('copy success!');
});
} else {
$input.select();
}
//document.execCommand('copy');
$input.blur();
});