web-dev-qa-db-fra.com

Quelle est la théorie derrière jQuery keypress, keydown, keyup black magic (sur Mac)?

Je suis confus au sujet des divers comportements de pression sur la touche, keydown, et keyup. Il me semble que j'ai raté une importante documentation qui explique les subtilités et les nuances de ce trio. Quelqu'un pourrait-il m'aider à déterminer quel document je dois lire afin d'utiliser plus efficacement ces événements? Si vous souhaitez des détails, voir ci-dessous.

@ o.v .: vous m'avez demandé de montrer du code, mais ce n'est pas vraiment un problème spécifique dans le code que j'essaie de résoudre. J'essaie de comprendre les comportements de ces gestionnaires d'événements et je demande à quelqu'un qui les comprend de me diriger vers une bonne documentation.

J'utilise jQuery pour créer un formulaire de saisie et l'insérer dans mon document. Cela fonctionne très bien, surtout. Je veux que le formulaire réponde au clavier comme la plupart des autres formulaires de saisie que je vois: esc La clé doit fermer le formulaire de la même manière que cliquer sur le bouton Annuler, et parce que le formulaire contient un <textarea>cmd + enter devrait être la même chose que de cliquer sur le bouton OK . Il semble assez simple d'utiliser l'événement keypress. Le problème est que Chrome n'appelle pas mon gestionnaire keypress pour le esc clé ou cmd + enter. Il tire pour ctrl + enter et option + enter et pour les alphanumériques, mais pas cmd + enter.

Je vais donc utiliser keyup à la place. Je reçois keyup pour escet keyup pour cmdet keyup pour enter, génial. Mais je ne reçois pas keyup pour le enter clé pendant que je tiens cmd.

La troisième fois est le charme, vous pourriez penser que keydown semble fonctionner, mais avec keydown, vous obtenez des clés de répétition. Je sais, tout ce que vous avez à faire est de dissocier le gestionnaire la première fois que vous êtes appelé, mais il semble étrange que les trois types d'événements se comportent différemment. Pourquoi est-ce? Y a-t-il un document évident que je n'ai évidemment pas lu?

49
SaganRitual

Keypress :


L'événement keypress est envoyé à un élément lorsque le navigateur enregistre la saisie au clavier. Ceci est similaire à l'événement keydown, sauf dans le cas de répétitions de touches. Si l'utilisateur appuie et maintient une touche, un événement de frappe est déclenché une fois, mais des événements de pression de touche distincts sont déclenchés pour chaque caractère inséré. De plus, touches de modification (comme Shift) déclenchent des événements de keydown mais pas des événements de pression de touche.

Keydown :


L'événement keydown est envoyé à un élément lorsque l'utilisateur appuie d'abord sur une touche du clavier. Il peut être attaché à n'importe quel élément, mais l'événement n'est envoyé qu'à l'élément qui a le focus. Les éléments pouvant faire l'objet d'un focus peuvent varier selon les navigateurs, mais les éléments de formulaire peuvent toujours être ciblés, tout comme les candidats raisonnables pour ce type d'événement.

Keyup :


L'événement keyup est envoyé à un élément lorsque l'utilisateur relâche une touche du clavier. Il peut être attaché à n'importe quel élément, mais l'événement n'est envoyé qu'à l'élément qui a le focus. Les éléments pouvant être mis au point peuvent varier d'un navigateur à l'autre, mais les éléments de formulaire peuvent toujours être mis en évidence, tout comme les candidats raisonnables pour ce type d'événement.

En outre, il s'agit d'une information pratique qui est généralement passée sous silence:


Si des touches doivent être capturées n'importe où (par exemple, pour implémenter des touches de raccourci globales sur une page), il est utile d'attacher ce comportement à l'objet - document. En raison de la propagation d'événements, toutes les pressions sur les touches remonteront le DOM jusqu'à l'objet document, sauf si elles sont explicitement arrêtées.

Pour déterminer quel caractère a été entré, examinez l'objet événement transmis à la fonction de gestionnaire. Alors que les navigateurs utilisent des propriétés différentes pour stocker ces informations, jQuery normalise la propriété . Which afin que vous puissiez l'utiliser de manière fiable pour récupérer le code de caractère.

Notez que keydown et keyup fournissent un code indiquant quelle touche est enfoncée, tandis que la pression de touche indique quel caractère a été entré. Par exemple, un "a" en minuscule sera signalé comme 65 par keydown et keyup, mais comme 97 par pression de touche. Un "A" majuscule est signalé comme 65 par tous les événements. En raison de cette distinction, lors de la capture de touches spéciales telles que les touches fléchées, .keydown () ou .keyup () est un meilleur choix.

Plus d'informations concernant la touche cmd sur les MAC: code de clé jQuery pour la touche de commande

89
Chase

Cet article est une bonne ressource expliquant les différences entre keyup, keydown et keypress.

La réponse courte est qu'il n'y a pas d'autre moyen simple de les gérer que de prendre en compte les différents navigateurs.

La façon dont je le gère personnellement dans un plugin Bootstrap que j'ai écrit consiste à créer une méthode personnalisée pour vérifier quel événement est pris en charge. Par coïncidence, une méthode très similaire est apparue dans la version officielle Bootstrap un peu plus tard: P

//------------------------------------------------------------------
//
//  Check if an event is supported by the browser eg. 'keypress'
//  * This was included to handle the "exhaustive deprecation" of jQuery.browser in jQuery 1.8
//
eventSupported: function(eventName) {         
    var isSupported = (eventName in this.$element);

    if (!isSupported) {
      this.$element.setAttribute(eventName, 'return;');
      isSupported = typeof this.$element[eventName] === 'function';
    }

    return isSupported;
}

Plus tard, je l'utilise dans mon code pour attacher des gestionnaires d'événements:

if (this.eventSupported('keydown')) {
  this.$element.on('keydown', $.proxy(this.keypress, this));
}
5
Terry

Vous devez vous rappeler que lors de la validation d'un KeyboardEvent sur un mac, la touche de modification ne sera pas récupérée comme event.ctrlKey mais plutôt un event.metaKey. Une documentation supplémentaire est disponible sur MDN .

Sans voir aucun code, je parie que c'est la raison de ⌘+Enter pas récupéré.

1
o.v.