web-dev-qa-db-fra.com

JavaScript execCommand ('copie') ne fonctionne pas

Je ne parviens pas à utiliser l'execCommand ("copie"), en essayant de copier la valeur sélectionnée dans l'option de sélection multiple. iam obtient une valeur dans "temp" mais la valeur qui est dans temp ne se copie pas ou n'entre pas dans le presse-papiers.

{
        $propArr=array_unique($properties);
        echo "<div class='table-responsive'>";
            echo "<table class='bordered'>";
            foreach($propArr as $keyProp =>$val){
                echo "<tr>";
                    echo "<td>$val</td><td>";
                    echo "<select name='propval' id='propval' onclick='showpropval(this.value);' class='form-control' multiple>";
                    foreach($values as $k => $v){
                        if($val==$k){
                            foreach($v as $kv =>$fval){
                                echo "<option value='$fval'>$fval</option>";
                            }
                        }
                    }
                    echo "</select>";
                    echo"</td>";
                echo "</tr>";
            }
            echo "</table>";
        echo "</div>";
        }

<script>
        function showpropval(val)
        {
            var temp = val;
            temp.execCommand("copy");

        }
    </script>
4
Rajesh k

Je comprends que votre intention est la suivante: vous souhaitez copier les valeurs des options sélectionnées dans le presse-papiers dès que vous les sélectionnez.

Lorsque vous utilisez document.execCommand('copy'), vous copiez tout ce qui est sélectionné sur la page (tel que le contenu d'un paragraphe ou d'un champ de saisie lui-même).

Le hic, c'est que la sélection d'options dans <select> n'est pas considéré comme du texte sélectionné. Pire encore, si vous souhaitez déclencher la sélection de texte via javascript, il existe certaines restrictions: vous ne pouvez appeler . Select () sur un <input>ou un <textarea> élément.

Voici ce que je ferais: copier les options sélectionnées dans un champ de saisie séparé (non visible), le sélectionner et copier le contenu de celui-ci.

Voici un violon qui peut servir de démo: https://jsfiddle.net/Zomry/metcfvcq/13/

Je vais le décomposer ici:

Tout d'abord, ajoutez cet élément à la page. Il s'agit du champ de saisie où nous allons copier le contenu du presse-papiers. Notez que j'ai ajouté tabindex -1 afin que vous ne puissiez pas l'atteindre via la touche de tabulation. J'ai également inclus aria-hidden afin que les lecteurs d'écran sachent qu'il doit ignorer cela.

<input class='copyfrom' tabindex='-1' aria-hidden='true'>

Ensuite, rendez le champ de saisie invisible en le mettant hors écran (ne fonctionnait pas si j'essayais d'afficher: aucun; ou d'autres astuces)

<style>
    .copyfrom {
        position: absolute;
        left: -9999px;
    }
</style>

Copiez ensuite la valeur dans le champ de saisie, sélectionnez-la et copiez-la.

var input = document.querySelector("input.copyfrom"); // select the input field

function showpropval(val) {
    var selectedValues = getSelectValues(this); // get selected values
    input.value = test.join(','); // join them in a comma separated list
    input.select(); // select offscreen inputs text
    document.execCommand("copy"); // copy it
    this.focus(); // focus back on original, so we don't see any glitches
} 

// credits to: https://stackoverflow.com/questions/5866169/how-to-get-all-selected-values-of-a-multiple-select-box
function getSelectValues(select) {
    var result = [];
    var options = select && select.options;
    var opt;

    for (var i=0, iLen=options.length; i<iLen; i++) {
        opt = options[i];

        if (opt.selected) {
          result.Push(opt.value || opt.text);
        }
    }
  return result;
}
4
Zomry

fonction CopyToClipboard (élément) {

            var $temp = $("<input>");
            $("body").append($temp);
            $temp.val($(element).text()).select();
            document.execCommand("copy", false, $temp.val());
            $temp.remove();




        }
1
Hina Azhar

J'ai eu un autre cas de commande "copier" ne fonctionnant pas. ExecCommand a renvoyé true, mais la valeur n'a pas été copiée. Dans mon cas, le problème était la fonction qui exécutait la commande (une promesse, pour être exact). Peut-être un petit échantillon (en utilisant la fonction de la réponse de Zomry):

function copyToClipboardButtonHandler_Working() {
  //copy logic executed directly here works
  showpropval('this works');
}

function copyToClipboardButtonHandler_NotWorking() {
  //copy logic executed directly here works
  myService.doSomeLogicAndReturnPromiseWithAString().then(text =>
     showpropval(text) /*this does NOT work'*/
  );
}

Si j'interprète correctement, la commande doit être invoquée dans la même itération d'exécution de script qui a été invoquée par un humain. Étant donné que le rappel de Promise est dans une autre itération, le navigateur le nie (bien qu'il dise que non). Je ne sais pas si c'est vrai, mais le code fonctionne pour moi, ce qui est bien;)

1
Sielu

ok, mon approche est un peu plus simple:

  1. créer une entrée supplémentaire avec le type 'texte'
  2. lors de votre appel de fonction, copiez la valeur de l'option sélectionnée dans le champ supplémentaire
  3. donner une position de champ supplémentaire absolue et gauche -9999 pour qu'elle existe dans dom mais pas dans la fenêtre visible!
  4. fais le reste!

voici un exemple:

function copyUserName() {

    //just_for_copy is my invisible extra field
    document.getElementById('just_for_copy').value = document.getElementById('user_phone').value;

    var justForCopy = document.getElementById('just_for_copy');

    justForCopy.select();

    document.execCommand("copy");
}
1
Alireza Noori

Essaye ça:

function showpropval(val) {
    var temp = val;
    document.execCommand("copy",false,val);
}
0
ledaivuong

Pas directement lié mais semble être un bon endroit pour le dire. Lors de l'utilisation de document.execCommand (), l'élément utilisé pour fournir le "texte" doit être visible sur la page. Donc, en utilisant display: none; entraînera l'échec de cette tentative également de rendre la hauteur de l'élément: 0; largeur: 0; rompt également cette fonction. J'ai contourné cela, mais en positionnant l'élément de façon absolue et en le déplaçant loin de l'écran.

J'espère que cela aide quelqu'un :-)

0
john