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

sur la page d'accueil d'un site que je suis en train de construire, plusieurs <div> s utilisent la pseudo-classe CSS :hover pour ajouter une bordure lorsque la souris les survole. Un des <div> s contient un <form> qui, en utilisant jQuery, gardera la frontière si une entrée à l'intérieur de lui a la mise au point. Cela fonctionne parfaitement sauf que IE6 ne supporte pas :hover sur tout élément autre que <a> S. Donc, pour ce navigateur seulement nous utilisons jQuery pour imiter CSS :hover en utilisant le $(#element).hover() méthode. Le seul problème est que, maintenant que jQuery gère à la fois le formulaire focus() et hover() , lorsqu'une entrée a un focus, alors l'utilisateur déplace la souris, la frontière disparaît.

je pensais que nous pourrions utiliser une sorte de conditionnel pour arrêter ce comportement. Par exemple, si nous testons à la souris si l'une des entrées a la mise au point, nous pourrions empêcher la frontière de disparaître. AFAIK, il n'y a pas de sélecteur :focus à jQuery, donc je suis vous ne savez pas comment faire cela. Des idées?

508
demandé sur Michał Perłakowski 2009-06-09 01:21:01

15 réponses

jQuery 1.6+

jQuery a ajouté un sélecteur :focus de sorte que nous n'avons plus besoin de l'Ajouter nous-mêmes. Il suffit d'utiliser $("..").is(":focus")

jQuery 1.5 et inférieur

Edit: Comme les temps ont changé, nous avons trouver de meilleures méthodes pour les tests de focus, le nouveau favori est ce gist de Ben Alman :

jQuery.expr[':'].focus = function( elem ) {
  return elem === document.activeElement && ( elem.type || elem.href );
};

D'après Mathias Bynens ici :

notez que le test (elem.type || elem.href) a été ajouté pour filtrer les faux positifs comme le corps. De cette façon, nous nous assurons de filtrer tous les éléments sauf les contrôles de formulaires et les hyperliens.

vous définissez un nouveau sélecteur. Voir Plugins/Création De . Alors vous pouvez faire:

if ($("...").is(":focus")) {
  ...
}

ou:

$("input:focus").doStuff();

Any jquery

si vous voulez juste comprendre quel élément a la mise au point, vous pouvez utiliser

$(document.activeElement)

si vous n'êtes pas sûr que la version sera 1.6 ou moins, vous pouvez ajouter le sélecteur :focus s'il manque:

(function ( $ ) {
    var filters = $.expr[":"];
    if ( !filters.focus ) { 
        filters.focus = function( elem ) {
           return elem === document.activeElement && ( elem.type || elem.href );
        };
    }
})( jQuery );
860
répondu gnarf 2017-05-23 12:03:05

CSS:

.focus {
    border-color:red;
}

JQuery:

  $(document).ready(function() {

    $('input').blur(function() {
        $('input').removeClass("focus");
      })
      .focus(function() {
        $(this).addClass("focus")
      });
  });
44
répondu Daniel Moura 2015-04-07 15:22:11

Voici une réponse plus robuste que celle actuellement acceptée:

jQuery.expr[':'].focus = function(elem) {
  return elem === document.activeElement && (elem.type || elem.href);
};

notez que le test (elem.type || elem.href) a été ajouté pour filtrer les faux positifs comme body . De cette façon, nous nous assurons de filtrer tous les éléments sauf les contrôles de formulaires et les hyperliens.

(extrait de ce gist par Ben Alman .)

19
répondu Mathias Bynens 2011-03-22 12:58:29

Mise À Jour D'Avril 2015

puisque cette question est posée depuis longtemps, et que de nouvelles conventions sont entrées en vigueur, je pense que je devrais mentionner que la méthode .live a été dépréciée.

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

leur documentation est très utile pour expliquer son fonctionnement;

The .() la méthode attache des gestionnaires d'événement pour l'ensemble sélectionné des éléments de l'objet jQuery. Comme de jQuery 1.7, l' .() la méthode fournit toutes les fonctionnalités nécessaires pour fixer les gestionnaires d'événements. Pour aide à la conversion des anciennes méthodes jQuery event, voir .lier(), .délégué(), et .vivre.)(

donc, pour que vous cibliez 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 permet même d'utiliser la touche de TABULATION.

13
répondu jbutler483 2016-09-08 17:36:51

Je ne suis pas tout à fait sûr de ce que vous cherchez, mais on dirait que cela peut être réalisé en stockant l'état des éléments d'entrée (ou le div?) comme variable:

$('div').each(function(){

    var childInputHasFocus = false;

    $(this).hover(function(){
        if (childInputHasFocus) {
            // do something
        } else { }
    }, function() {
        if (childInputHasFocus) {
            // do something
        } else { }
    });

    $('input', this)
        .focus(function(){
            childInputHasFocus = true;
        })
        .blur(function(){
            childInputHasFocus = false;
        });
});
2
répondu James 2009-06-08 21:37:31

Une alternative à l'utilisation des classes pour marquer l'état d'un élément, c'est la "151930920 magasin de données" fonctionnalité .

P. S.: Vous pouvez stocker des booléens et tout ce que vous désirez en utilisant la fonction data() . Ce n'est pas seulement à propos des chaînes :)

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

et puis c'est juste une question d'accéder à l'état des éléments.

1
répondu cllpse 2009-06-09 11:30:07

avez-vous pensé à utiliser mouseOver et mouseOut pour simuler ceci. Aussi regarder dans mouseEnter et mouseLeave

1
répondu mkoryak 2017-10-24 06:23:06

garder une trace des deux états (planés, focalisés) comme des drapeaux true/false, et chaque fois qu'on change, exécuter une fonction qui supprime la frontière si les deux sont false, sinon affiche la frontière.

Donc: onfocus jeux de concentré = true, onblur jeux de concentré = false. onmouseover jeux planait = true, onmouseout jeux planait = false. Après chacun de ces événements exécuter une fonction qui ajoute/supprime la frontière.

0
répondu Blixt 2009-06-08 21:35:40

autant que je sache, vous ne pouvez pas demander au navigateur si une entrée sur l'écran a une mise au point, vous devez configurer une sorte de suivi de mise au point.

j'ai habituellement une variable appelée" noFocus " et je la mets à true. Puis j'ajoute un événement focus à toutes les entrées qui rend noFocus false. Puis j'ajoute un événement flou à toutes les entrées qui ramènent noFocus à true.

j'ai une classe MooTools qui gère cela assez facilement, je suis sûr que vous pourriez créer un plugin jquery à faire de même.

une fois que c'est créé, vous pouvez vérifier noFocus avant de faire n'importe quel échange de Frontière.

0
répondu Ryan Florence 2009-06-08 21:36:40

il n'y a pas: focus, mais il y a :selected http://docs.jquery.com/Selectors/selected

mais si vous voulez changer l'apparence des choses en fonction de ce qui est sélectionné, vous devriez probablement travailler avec les événements flou.

http://docs.jquery.com/Events/blur

0
répondu Chris Brandsma 2009-06-08 21:38:14

il y a un plugin pour vérifier si un élément est focalisé: http://plugins.jquery.com/project/focused

$('input').each(function(){
   if ($(this) == $.focused()) {
      $(this).addClass('focused');
   }
})
0
répondu Murat Çorlu 2009-11-12 09:05:16

j'ai eu un .l'événement live("focus") est 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).sélectionnez();

à cause des bizarreries entre les différents navigateurs, Le select serait parfois remplacé par le clic qui l'a causé, et il désélectionnerait le contenu juste après en faveur de placer le curseur dans le champ de texte (a fonctionné la plupart du temps ok en FF mais a échoué in IE)

j'ai pensé que je pourrais résoudre cela en mettant un léger retard sur le select...

setTimeout (function () {$(formObj).sélectionner();},200);

cela fonctionnait bien et le select persistait, mais un drôle de problème est apparu.. Si vous affichez d'un champ à l'autre, le focus passe au champ suivant avant que le select n'ait lieu. Puisque select vole focus, le focus retournerait alors et déclencherait un nouvel événement "focus". Ce se retrouvant dans une cascade de sélections d'entrée dansant partout sur l'écran.

une solution réalisable serait de vérifier que le champ a toujours la mise au point avant d'exécuter select(), mais comme mentionné, il n'y a pas de façon simple de vérifier... J'ai fini par me passer de la mise en évidence automatique, plutôt que de transformer ce qui devrait être un seul appel jQuery select() en une énorme fonction chargée de sous-programmes...

0
répondu Brian 2011-09-08 19:56:19

si quelqu'un s'en soucie, il y a une bien meilleure façon de capter focus now, $(foo).focus(...)

http://api.jquery.com/focus /

0
répondu CrackSmoker9000 2014-10-30 04:13:17

ce que j'ai fini par faire est de créer une classe arbitraire appelée .elementhasfocus qui est ajouté et supprimé dans la fonction jQuery focus (). Quand la fonction hover () s'exécute à 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 ont focus) la bordure est supprimé. Sinon, rien ne se passe.

0
répondu bloudermilk 2016-09-26 20:28:57

Simple

 <input type="text" /> 



 <script>
     $("input").focusin(function() {

    alert("I am in Focus");

     });
 </script>
-1
répondu Code Spy 2012-03-16 07:28:22