web-dev-qa-db-fra.com

Capturez les touches tapées sur Android utilisant javascript

J'ai une page Web avec une zone de texte et j'ai besoin de capturer les clés tapées par l'utilisateur (afin de pouvoir substituer différents caractères Unicode aux clés tapées). Mon code actuel est le suivant:

$("#myTextArea").bind('keypress', function(event) {

    var keyInput = event.which;
   // call other functions

});

Ce code ci-dessus fonctionne sur les PC et iPhone/Safari. Cependant, il échoue lors de l'utilisation de la tablette Chrome sur un Android (samsung). Pour une raison quelconque, lorsque je tape sur le clavier virtuel (doux) Android, l'événement "keypress" n'est pas déclenché. La Android est 5.0.2.

Si j'essaie d'utiliser "keyUp" ou "keyDown", il renvoie toujours 229 pour tous les caractères (sauf pour la touche retour, l'espace, le retour arrière, etc.).

Même si le keyCode est toujours 229, la zone de texte affiche les caractères corrects saisis par l'utilisateur. Ce qui signifie que l'appareil sait quelle clé a été entrée, mais d'une manière ou d'une autre, je ne parviens pas à gérer cet événement (et le code de clé) à l'aide de javascript.

Voici les alternatives que j'ai essayées jusqu'à présent, et leurs résultats:

$("#mainTextArea").on("keydown keyup", function(event) { 
    // event.which and event.keyCode both return 229

$(document).on('keypress', function(event) { 
    // function is not triggered

$('#myTextArea').bind('input keypress', function(event) { 
   // comes inside function, but keyCode and which are undefined

Toute aide concernant ce problème est appréciée.

32
agentwarn

Malheureusement, il semble que vous ne puissiez pas faire grand-chose ici. L'événement Keypress est obsolète et n'est donc pas déclenché. 229 à la montée et à la descente indique que la mémoire tampon du clavier est occupée. La raison - lorsque vous appuyez sur une touche - l'entrée n'est toujours pas garantie d'être ce que l'utilisateur a appuyé, en raison de la suggestion automatique et d'autres événements qui peuvent suivre immédiatement et invalider l'événement. Bien qu'à mon avis, il aurait été préférable d'envoyer la clé en premier, puis de déclencher un autre événement peut-être sur la suggestion automatique afin que vous puissiez agir séparément ...

La seule chose que je sache actuellement est d'attacher aux deux - keydown et keyup, stocker la valeur sur keydown, obtenir la valeur sur keyup et trouver le delta, qui est ce que l'utilisateur a appuyé. Malheureusement, cela ne fonctionnera pas pour les contrôles sans entrée (par exemple - le corps ou quelque chose comme ça). Peut-être pas ce que vous voulez entendre comme réponse, mais quand même.

10
Pavel Donchev

J'ai rencontré le même problème. Plusieurs explications sont disponibles, mais de toute façon, il semble étrange qu'aucune solution ne soit proposée. Pour le moment, je l'ai résolu en capturant l'événement oninput .

"Cet événement est similaire à l'événement onchange. La différence est que l'événement oninput se produit immédiatement après que la valeur d'un élément a changé, tandis que onchange se produit lorsque l'élément perd le focus, après que le contenu a été modifié"

Cet événement prend également en charge le texte inséré, à partir du texte collé ou des corrections et suggestions.

cela ne me donne pas la solution parfaite car je ne peux manipuler le texte qu'après qu'il a été saisi, mais pour le moment c'est le meilleur que j'ai.

Si quelqu'un a une meilleure solution, je serai heureux d'en entendre parler.

6
user2299401

Je suis tombé sur cette discussion en faisant des recherches pour un projet sur lequel je travaillais. J'ai dû créer des masques de saisie pour une application mobile et réponse de Pavel Donchev m'a fait réfléchir à ce qui pourrait fonctionner pour capturer des clés dans Android. Dans mon projet spécifique, keydown et keyup ne suffiraient pas car l'événement keyup n'est déclenché qu'après la libération d'une clé, donc cela impliquerait une validation tardive, j'ai donc fait plus de recherches (et beaucoup d'essais et d'erreurs) avec les événements d'entrée et l'a fait fonctionner.

var input = document.getElementById('credit-card-mask'),
    oldValue,
    newValue,
    difference = function(value1, value2) {
      var output = [];
      for(i = 0; i < value2.length; i++) {
        if(value1[i] !== value2[i]) {
          output.Push(value2[i]);
        }
      }
      return output.join("");
    },
    keyDownHandler = function(e) {
      oldValue = input.value;
      document.getElementById("onkeydown-result").innerHTML = input.value;
    },
    inputHandler = function(e) {
      newValue = input.value;
      document.getElementById("oninput-result").innerHTML = input.value;
      document.getElementById("typedvalue-result").innerHTML = difference(oldValue, newValue);
    }
;

input.addEventListener('keydown', keyDownHandler);
input.addEventListener('input', inputHandler);
<input type="text" id="credit-card-mask" />
<div id="result">
  <h4>on keydown value</h4>
  <div id="onkeydown-result"></div>
  <h4>on input value</h4>
  <div id="oninput-result"></div>
  <h4>typed value</h4>
  <div id="typedvalue-result"></div>
</div>

L'événement oninput est déclenché juste après l'événement keydown, ce qui est le moment idéal pour mes validations.

J'ai compilé le tout dans un article. Si vous êtes curieux, vous pouvez en lire plus ici .

4
Glauber Borges

Il y a un événement textInput qui vous donne le caractère entré

const inputField = document.getElementById('wanted-input-field');

inputField.addEventListener('textInput', function(e) {
    // e.data will be the 1:1 input you done
    const char = e.data; // In our example = "a"

    // If you want the keyCode..
    const keyCode = char.charCodeAt(0); // a = 97

    // Stop processing if "a" is pressed
    if (keyCode === 97) {
        e.preventDefault();
        return false;
    }
    return true;
});
2
reyiyo

vérifiez simplement vos caractères d'entrée keyCode, si c'est 0 ou 229 alors voici la fonction getKeyCode () qui utilise charCodeAt de JS pour retourner le KeyCode qui prend la chaîne d'entrée un paramètre et renvoie le code clé du dernier caractère.

<script>
        var getKeyCode = function (str) {
            return str.charCodeAt(str.length);
        }


        $('#myTextfield').on('keyup',function(e){

            //for Android chrome keycode fix
            if (navigator.userAgent.match(/Android/i)) {

                var inputValue = this.value;

                var charKeyCode = e.keyCode || e.which;
                if (charKeyCode == 0 || charKeyCode == 229) { 
                    charKeyCode = getKeyCode(inputValue);
                    alert(charKeyCode+' key Pressed');
                }else{
                   alert(charKeyCode+' key Pressed');
                    }
            }       
        });
    </script>
2
Akshay Tilekar

J'ai récemment implémenté une fonctionnalité de "mentions" dans la dernière version de notre application de messagerie électronique Astro AI. Fondamentalement, vous tapez "@" dans notre vue Web de composition et vous obtenez une liste de suggestions de saisie semi-automatique. Comme la plupart des gens, nous avons eu des problèmes pour résoudre ce problème avec Javascript. Ce qui a finalement fonctionné était une solution native. Si vous @Override la méthode onCreateInputConnection () du WebView, vous pouvez encapsuler le résultat super.onCreateInputConnection () (qui n'est qu'une interface InputConnection) avec une classe personnalisée. Ensuite, dans votre implémentation de wrapper, vous pouvez intercepter les entrées via commitText () ou setComposingText () ou peut-être une autre méthode spécifique à ce que vous recherchez ... comme les suppressions. Je ne sais pas si vous obtiendrez des rappels sur les caractères de contrôle comme les flèches haut et bas, mais peut-être que cela peut être un point de départ pour résoudre votre problème spécifique.

1
Anthony Lee