jQuery obtient la valeur d'entrée après avoir appuyé sur une touche

129

J'ai la fonction suivante:

$(document).ready(function() {
    $("#dSuggest").keypress(function() {
        var dInput = $('input:text[name=dSuggest]').val();
        console.log(dInput);
        $(".dDimension:contains('" + dInput + "')").css("display","block");
    });
});

Pour une raison quelconque, pour la première pression sur une touche, j'obtiens une chaîne vide dans le journal de la console.

Ou Weinberger
la source

Réponses:

157

Cela est dû au fait que les keypressévénements sont déclenchés avant que le nouveau caractère ne soit ajouté à l' valueélément (le premier keypressévénement est déclenché avant l'ajout du premier caractère, alors que le valueest toujours vide). Vous devriez utiliser à la keyupplace, qui est déclenché après que le personnage a été ajouté.

Notez que si votre élément #dSuggestest le même que input:text[name=dSuggest]vous pouvez simplifier considérablement ce code (et si ce n'est pas le cas, avoir un élément avec un nom qui est le même que celui idd'un autre élément n'est pas une bonne idée).

$('#dSuggest').keypress(function() {
    var dInput = this.value;
    console.log(dInput);
    $(".dDimension:contains('" + dInput + "')").css("display","block");
});
seul jour
la source
2
Fonctionne, mais avec jquery 2.x out, c'est maintenant obsolète car la réponse ci-dessous en utilisant on et input est la meilleure façon de le faire maintenant.
Piotr Kula
1
@ppumkin: Ce n'est pas parce que jQuery 2 est sorti que les gens n'ont pas besoin de prendre en charge IE8 et les versions antérieures. Et je ne vois rien dans la documentation qui suggère une prise en charge réelle du inputtype d'événement.
cookie monster
7
Vous corrigez, ils devraient cesser de soutenir IE, point. La plupart des «solutions de contournement» dans jQuery 1.x sont pour IE, donc il devrait vraiment être renommé en jQuerIE.
Piotr Kula
189

Réalisant qu'il s'agit d'un article assez ancien, je vais quand même fournir une réponse car je luttais avec le même problème.

Vous devez utiliser l' "input"événement à la place et vous inscrire avec la .onméthode. C'est rapide - sans le décalage keyupet résout le dernier problème de pression de touche que vous décrivez.

$('#dSuggest').on("input", function() {
    var dInput = this.value;
    console.log(dInput);
    $(".dDimension:contains('" + dInput + "')").css("display","block");
});

Démo ici

Frederik Gottlieb
la source
26
Cela devrait être marqué comme une bonne réponse - keyup résout peut-être le problème de caractère manquant, mais est problématique pour déterminer si le caractère a été réellement écrit (et la clé n'était pas par exemple "tab" ou "home"). +1 pour vous
Nashi
Le problème est qu'il n'est pas pris en charge dans les anciens navigateurs et IE9 ne répond pas aux caractères supprimés.
PhoneixS
33

Utilisez .keyupau lieu d'appuyer sur une touche.

Utilisez également $(this).val()ou simplement this.valuepour accéder à la valeur d'entrée actuelle.

DÉMO ici

Informations sur les .keypressdocuments jQuery,

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

Selvakumar Arumugam
la source
5
keyupest trop lent, et une touche peut être maintenue enfoncée sans être relâchée et des choses doivent se passer. mieux utiliser keydownavec un peu de temps pour que la valeur change réellement.
vsync
le seul inconvénient que j'ai trouvé est que si l'utilisateur a appuyé sur plus d'un caractère du clavier ensemble, il ne s'enregistrera pas correctement.
vsync
5

Vous devez interrompre le thread d'exécution pour permettre la mise à jour de l'entrée.

  $(document).ready(function(event) {
       $("#dSuggest").keypress(function() {
           //Interrupt the execution thread to allow input to update
               setTimeout(function() {
                   var dInput = $('input:text[name=dSuggest]').val();
                   console.log(dInput);
                   $(".dDimension:contains('" + dInput + "')").css("display","block");
               }, 0);
       });
  });
parlement
la source
1
keyuple délai est trop lent à certaines fins et ne filtre pas automatiquement les touches de modification. Cela fonctionne mieux pour moi.
Albert Bori
meilleure réponse. keyup - lent et ne peut pas attraper les caractères comme @ avec deux touches enfoncées.
Roma Rush
4

Cela est dû au fait que l' Keypressévénement est déclenché avant l'ajout du nouveau personnage. Utilisez plutôt l'événement 'keyup', qui fonctionnera parfaitement dans votre situation.

$(document).ready(function() {
    $("#dSuggest").keyup(function() {
        var dInput = $('input:text[name=dSuggest]').val();
        console.log(dInput);
        $(".dDimension:contains('" + dInput + "')").css("display","block");
    });
});

Je veux ajouter à cela, si vous avez plusieurs zones de texte et que vous devez faire la même chose sur leur événement keyup, vous pouvez simplement leur donner une classe css commune (par exemple commoncss) et appliquer un événement keyup comme celui-ci.

$(document).ready(function() {
    $(".commoncss").keyup(function() {
        //your code
    });
});

cela réduira considérablement votre code car vous n'avez pas à appliquer l'événement keyup par id pour chaque zone de texte.

yogi
la source
3

Je cherchais un exemple ES6 (pour qu'il puisse passer mon linter) donc pour d'autres personnes qui recherchent le même:

$('#dSuggest').keyup((e) => {
    console.log(e.currentTarget.value);
});

J'utiliserais également keyup car vous obtenez la valeur actuelle qui est remplie.

MarvinVK
la source
1

Utilisez simplement un délai pour passer votre appel; le timeout sera appelé lorsque la pile d'événements sera terminée (c'est-à-dire après l'appel de l'événement par défaut)

$("body").on('keydown', 'input[type=tel]', function (e) {
    setTimeout(() => {
        formatPhone(e)
    }, 0)
});
Smonge
la source
0

Je pense que ce dont vous avez besoin est le prototype ci-dessous

$(element).on('input',function(){code})
Zuckerberg
la source
0

jQuery obtient la valeur d'entrée après avoir appuyé sur une touche

https://www.tutsmake.com/jquery-keypress-event-detect-enter-key-pressed/

i = 0;  
$(document).ready(function(){  
    $("input").keypress(function(){  
        $("span").text (i += 1);  
    });  
}); 
<!DOCTYPE html>  
<html>  
<head>  
<title>jQuery keyup() Method By Tutsmake Example</title> 
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>  
<body>  
Enter something: <input type="text">  
<p>Keypresses val count: <span>0</span></p>  
</body>  
</html>  

Développeur
la source