2017-05-09 1 views
1

J'utilise le JS suivant pour m'assurer que les touches numériques affectent une entrée de champ de texte, permettant à l'utilisateur d'appuyer vers le haut ou vers le bas pour changer le quantité d'entrée du champ de texte.Comment arrêter la fonction jQuery .focus() lorsque vous cliquez n'importe où sur la page

Veuillez noter que l'échange vers un champ numérique n'est pas une option viable, il doit rester un champ de texte.

Pour l'instant, ce code fonctionne lorsque vous cliquez sur le champ de saisie en utilisant .focus(), mais lorsque vous cliquez n'importe où en dehors de l'entrée, la page défile (comme il se doit) besoin d'empêcher cela). Je ne souhaite exécuter ce code que lorsque l'entrée est focalisée. Ainsi, lorsque vous cliquez n'importe où sur la page, les flèches haut et bas font simplement défiler la page comme d'habitude, sans affecter le numéro d'entrée du texte.

J'ai essayé event.preventDefault() et event.stopPropagation() dans chaque ligne pour essayer de l'arrêter, mais il me manque quelque chose. Je ne suis pas très bon avec JS, donc ce n'est pas évident pour moi et après des heures de recherche et de lecture de docs, je n'ai toujours pas eu de chance.

Merci d'avance!

jQuery(document).ready(function($) { 
 

 
    var $input = $('input.qty[type="text"]'); 
 

 
    $input.focus(function() { 
 
    $(document).on('keydown', function(event) { 
 
     if (event.which == 38 || event.which == 104) { 
 
     $input.val((parseInt($input.val()) + 1)); 
 
     } else if (event.which == 40 || event.which == 98) { 
 
     $input.val((parseInt($input.val()) - 1)); 
 
     } 
 
    }); 
 
    }); 
 
    
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<input class="qty" type="text">

+0

input.blur .... document.off ... – Ted

Répondre

2

changer simplement votre code pour que le feu la fonction d'événement sur keydown l'élément d'entrée.

également votre code a quelques défauts:

  1. Binding le gestionnaire d'événements $(document).on(...)à l'intérieur l'événement $input.focus provoque le code à insérer un nouveau gestionnaire d'événements chaque fois vous concentrer le champ d'entrée, ce qui pour tirer plusieurs fois. Au début il/diminue de 1, puis par 2, 3, etc.

  2. Vous pouvez d'abord vérifier la valeur de l'entrée pour obtenir un nombre valide, ou vous obtiendrez NaN comme valeur. Pourquoi ne pas utiliser type="number" pour cela? La plupart des navigateurs intègrent la fonctionnalité souhaitée "gratuitement" pour ce type et en haut quelques flèches sur lesquelles cliquer.

$(document).ready(function($) { 
 

 
    var $input = $('input[type=text]'); 
 

 
    // use $input instead document here 
 
    $input.on('keydown', function(event) { 
 

 
    var val = parseInt($input.val(),10); 
 
    if (isNaN(val)) { 
 
     val = 0; 
 
    } 
 

 
    if (event.which == 38 || event.which == 104) { 
 
     val++; 
 
    } else if (event.which == 40 || event.which == 98) { 
 
     val--; 
 
    } 
 

 
    $input.val(val); 
 

 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<input type="text" /> 
 
<div> 
 
Input with "type='number'" does this automatically:<br> 
 
<input type="number" /> 
 
</div>

Juste pour le plaisir, une version fantaisie ES6 ressemblerait à ce qui suit:

$input.on('keydown', function(event) { 
    let val = parseInt($input.val())||0; 
    val=([38,104].includes(event.which))?++val:[40,98].includes(event.which)?--val:val; 
    $input.val(val); 
}); 
+0

J'utilise 'type =" text "' pour styliser le champ (ajouter les boutons plus et moins au champ au lieu du nombre du navigateur). –

+0

Je reçois une erreur d'analyse lors de la réduction de cette 'SyntaxError: Jeton inattendu: name (val)'. Y a-t-il un autre moyen de vérifier un nombre valide? –

+0

Peut-être que votre analyseur ne supporte pas le mot clé 'let', il suffit de le remplacer par un' var' normal, je change le code en conséquence. – Christoph

3

faire comme ceci:

jQuery(document).ready(function ($) { 
 
    var $input = $('input.qty[type="text"]'); 
 
    // $input.focus(function() { 
 
     $input.on('keydown', function (event) { 
 
      if (event.which == 38 || event.which == 104) { 
 
       $input.val((parseInt($input.val()) + 1)); 
 
      } else if (event.which == 40 || event.which == 98) { 
 
       $input.val((parseInt($input.val()) - 1)); 
 
      } 
 
     }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<input type="text" class = "qty">

Vous venez d'ajouter un if($input.is(":focus")) pour vérifier si votre entrée a le focus.

--EDIT--

Comme indiqué, l'événement keydown n'a pas besoin d'être attaché à l'ensemble du document. L'attacher à juste l'entrée sera meilleur et résoudra également le problème de mise au point. Mise à jour de l'extrait

+0

Imo overkill pour que l'événement cible soit l'ensemble du document. – Christoph

+0

Vous avez raison. Mise à jour de l'extrait – gaganshera