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


Sur la première page d'un site que je construis, plusieurs <div>s utiliser le CSS :hover pseudo-classe pour ajouter une bordure lorsque la souris est sur eux. Un de <div>s contient un <form> qui, à l’aide de jQuery, conservera la bordure si une entrée est active. Cela fonctionne parfaitement, sauf que IE6 ne prend pas en charge :hover sur tous les éléments autres 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, maintenant que jQuery gère à la fois le formulaire 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 condition 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 :focus sélecteur dans jQuery, donc je ne sais pas comment faire cela. Des idées?


498
2018-06-08 21:21


origine


Réponses:


jQuery 1.6+

jQuery a ajouté un :focus sélecteur donc nous n'avons plus besoin de l'ajouter nous-mêmes. Juste utiliser $("..").is(":focus")

jQuery 1.5 et ci-dessous

Modifier: Comme les temps changent, nous trouvons de meilleures méthodes pour tester l'accent, le nouveau favori est cet aperçu de Ben Alman:

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

Cité de Mathias Bynens ici:

Notez que le (elem.type || elem.href) test 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 formulaire et les hyperliens.

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

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

ou:

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

Tout jQuery

Si vous voulez juste savoir quel élément a le focus, vous pouvez utiliser

$(document.activeElement)

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

(function ( $ ) {
    var filters = $.expr[":"];
    if ( !filters.focus ) { 
        filters.focus = function( elem ) {
           return elem === document.activeElement && ( elem.type || elem.href );
        };
    }
})( jQuery );

852
2018-06-08 21:41



CSS:

.focus {
    border-color:red;
}

JQuery:

  $(document).ready(function() {

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

43
2018-03-22 12:58



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 (elem.type || elem.href) test a été ajouté pour filtrer les faux positifs comme body. De cette façon, nous nous assurons de filtrer tous les éléments à l'exception des contrôles de formulaire et des liens hypertexte.

(Pris à partir de cet essentiel par Ben Alman.)


19
2018-04-07 15:27



Mise à jour d'avril 2015

Depuis que cette question existe depuis quelque temps et que de nouvelles conventions ont été adoptées, je pense que je devrais mentionner .live la méthode a été amortie.

À sa place, le .on la méthode 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 actuellement sélectionné   des éléments dans l'objet jQuery. A partir de jQuery 1.7, la méthode .on ()   fournit toutes les fonctionnalités requises pour attacher des gestionnaires d'événements. Pour   aide à la conversion à partir d'anciennes méthodes d'événement jQuery, voir .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.


13
2018-06-08 21:37



Je ne suis pas tout à fait sûr de ce que vous recherchez, mais cela peut sembler possible en stockant l'état des éléments d'entrée (ou le div?) En tant que 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
2018-06-09 11:30



Une alternative à l'utilisation de classes pour marquer l'état d'un élément est le fonctionnalité du magasin de données.

P.S .: Vous êtes capable de stocker des booléens et tout ce que vous désirez en utilisant le data() fonction. 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.


1
2018-06-08 21:29



Avez-vous pensé à utiliser mouseOver et mouseOut pour simuler cela. Aussi regarder dans sourisEnter et mouseLeave 


1
2018-06-08 21:35