[javascript] Utilisation de jQuery pour tester si une entrée a un focus


Answers

CSS:

.focus {
    border-color:red;
}

JQuery:

  $(document).ready(function() {

    $('input').blur(function() {
        $('input').removeClass("focus");
      })
      .focus(function() {
        $(this).addClass("focus")
      });
  });
Question

Sur la première page d'un site que je construis, plusieurs <div> s utilisent la pseudo-classe CSS :hover pour ajouter une bordure quand la souris les survole. L'un des <div> contient un <form> qui, en utilisant jQuery, conservera la bordure si une entrée à l'intérieur a le focus. Cela fonctionne parfaitement, sauf que IE6 ne prend pas en charge :hover tous les éléments autres que <a> s. Donc, pour ce navigateur seulement, nous utilisons jQuery pour imiter CSS :hover utilisant la méthode $(#element).hover() . Le seul problème est que maintenant que jQuery gère à la fois la forme focus() et hover() , lorsqu'une entrée a le focus, l'utilisateur déplace la souris vers l'intérieur et l'extérieur, la bordure disparaît.

Je pensais que nous pourrions utiliser une sorte de conditionnel pour arrêter ce comportement. Par exemple, si nous testions à la souris si l'une des entrées avait un focus, nous pourrions empêcher la frontière de disparaître. AFAIK, il n'y a pas de sélecteur de :focus dans jQuery, donc je ne suis pas sûr de savoir comment y arriver. Des idées?




Mise à jour d'avril 2015

Depuis que cette question existe depuis quelque temps et que de nouvelles conventions ont été .live , je pense que je devrais mentionner que la méthode des .live a été dépréciée.

À sa place, la méthode .on a maintenant été introduite.

Leur documentation est très utile pour expliquer comment cela fonctionne;

La méthode .on () associe des gestionnaires d'événements à l'ensemble d'éléments actuellement sélectionné dans l'objet jQuery. À partir de jQuery 1.7, la méthode .on () fournit toutes les fonctionnalités requises pour attacher des gestionnaires d'événements. Pour obtenir de l'aide sur la conversion d'anciennes méthodes d'événements jQuery, consultez .bind (), .delegate () et .live ().

Ainsi, pour que vous puissiez cibler l'événement 'input focused', vous pouvez l'utiliser dans un script. Quelque chose comme:

$('input').on("focus", function(){
   //do some stuff
});

C'est assez robuste et vous permet même d'utiliser la touche TAB.




Une alternative à l'utilisation de classes pour marquer l'état d'un élément est la fonctionnalité de stockage de données interne.

PS: Vous pouvez stocker des booléens et tout ce que vous désirez en utilisant la fonction data() . Ce n'est pas seulement une question de cordes :)

$("...").mouseover(function ()
{
    // store state on element
}).mouseout(function ()
{
    // remove stored state on element
});

Et puis c'est juste une question d'accès à l'état des éléments.




Un événement .live ("focus") était défini pour sélectionner () (surligner) le contenu d'une entrée de texte afin que l'utilisateur n'ait pas à le sélectionner avant de taper une nouvelle valeur.

$ (formObj) .select ();

En raison de bizarreries entre différents navigateurs, le select était parfois remplacé par le clic qui le provoquait, et il désélectionnait le contenu juste après en plaçant le curseur dans le champ de texte (fonctionnait généralement bien dans FF mais échouait dans IE)

Je pensais que je pourrais résoudre ce problème en mettant un léger retard sur la sélection ...

setTimeout (function () {$ (formObj) .select ();}, 200);

Cela fonctionnait bien et la sélection persistait, mais un drôle de problème se posait. Si vous étiez tabulé d'un champ à l'autre, le focus passerait au champ suivant avant la sélection. Puisque les interceptions sélectionnées se concentrent, la mise au point revient alors et déclenche un nouvel événement de "mise au point". Cela s'est terminé par une cascade de sélections d'entrée dansant sur tout l'écran.

Une solution réalisable serait de vérifier que le champ a toujours le focus avant d'exécuter le select (), mais comme mentionné, il n'y a pas de moyen simple de vérifier ... J'ai fini par me passer de toute la surbrillance automatique, plutôt que de tourner ce qui devrait être un simple appel select () jQuery dans une énorme fonction chargée de sous-routines ...




Gardez une trace des deux états (plané, concentré) comme drapeaux vrai / faux, et chaque fois que l'on change, exécutez une fonction qui supprime la bordure si les deux sont faux, sinon affiche la bordure.

Donc: onfocus définit focus = true, onblur définit focused = false. Onmouseover définit hovered = true, onmouseout définit hovered = false. Après chacun de ces événements, exécutez une fonction qui ajoute / supprime la bordure.







Ce que j'ai fini par faire est de créer une classe arbitraire appelée .elementhasfocus qui est ajoutée et supprimée dans la fonction jQuery focus (). Lorsque la fonction hover () s'exécute à la sortie de la souris, elle vérifie .elementhasfocus:

if(!$("#quotebox").is(".boxhasfocus")) $(this).removeClass("box_border");

Donc, s'il n'a pas cette classe (lire: aucun élément dans le div n'a de focus), la bordure est supprimée. Sinon, rien ne se passe.




Related