Usando jQuery per verificare se un input ha il focus

Sulla prima pagina di un sito che sto costruendo, diversi

s usano il CSS :hover pseudo-class per aggiungere un bordo quando il mouse è sopra di loro. Uno dei

s contiene un

che, usando jQuery, manterrà il bordo se un input al suo interno ha il focus. Funziona perfettamente tranne che IE6 non supporta :hover il :hover su qualsiasi elemento diverso da s. Quindi, per questo browser utilizziamo solo jQuery per simulare i CSS :hover passa il :hover usando il metodo $(#element).hover() . L’unico problema è che, ora che jQuery gestisce sia il modulo focus() che hover() , quando un input è attivo, l’utente sposta il mouse dentro e fuori, il bordo scompare.

Stavo pensando che potremmo usare un qualche tipo di condizionale per fermare questo comportamento. Ad esempio, se avessimo testato il mouse fuori se alcuni degli input erano focalizzati, avremmo potuto impedire che il confine andasse via. AFAIK, non c’è :focus selettore di :focus a :focus in jQuery, quindi non sono sicuro di come farlo accadere. Qualche idea?

    jQuery 1.6+

    jQuery ha aggiunto un :focus selettore di :focus quindi non è più necessario aggiungerlo da soli. Basta usare $("..").is(":focus")

    jQuery 1.5 e sotto

    Modifica: Con il passare del tempo, troviamo metodi migliori per testare la messa a fuoco, il nuovo preferito è questo essenza di Ben Alman :

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

    Citato da Mathias Bynens qui :

    Si noti che il (elem.type || elem.href) è stato aggiunto per filtrare i falsi positivi come il corpo. In questo modo, ci assicuriamo di filtrare tutti gli elementi tranne i controlli del modulo e i collegamenti ipertestuali.

    Stai definendo un nuovo selettore. Vedi Plugin / Authoring . Quindi puoi fare:

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

    o:

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

    Qualsiasi jQuery

    Se vuoi solo capire quale elemento ha il focus, puoi usare

     $(document.activeElement) 

    Se non sei sicuro che la versione sarà 1.6 o inferiore, puoi aggiungere il :focus selettore di :focus se manca:

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

    CSS:

     .focus { border-color:red; } 

    JQuery:

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

    Ecco una risposta più solida di quella attualmente accettata:

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

    Si noti che il (elem.type || elem.href) è stato aggiunto per filtrare i falsi positivi come il body . In questo modo, ci assicuriamo di filtrare tutti gli elementi tranne i controlli del modulo e i collegamenti ipertestuali.

    (Tratto da questo senso di Ben Alman .)

    Aggiornamento di aprile 2015

    Dato che questa domanda è in corso da un po ‘, e alcune nuove convenzioni sono entrate in gioco, sento che dovrei menzionare il metodo .live che è stato ammortizzato.

    Al suo posto, il metodo .on è stato ora introdotto.

    La loro documentazione è abbastanza utile per spiegare come funziona;

    Il metodo .on () collega i gestori di eventi al gruppo di elementi attualmente selezionato nell’object jQuery. A partire da jQuery 1.7, il metodo .on () fornisce tutte le funzionalità richieste per il collegamento di gestori di eventi. Per assistenza nella conversione da vecchi metodi di evento jQuery, vedere .bind (), .delegate () e .live ().

    Quindi, per poter indirizzare l’evento ‘input focused’, puoi usarlo in uno script. Qualcosa di simile a:

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

    Questo è abbastanza robusto e consente anche di usare il tasto TAB.

    Non sono del tutto sicuro di quello che stai cercando, ma sembra che possa essere ottenuto memorizzando lo stato degli elementi di input (o del div?) Come variabile:

     $('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; }); }); 

    Un’alternativa all’utilizzo delle classi per contrassegnare lo stato di un elemento è la funzionalità dell’archivio dati interno.

    PS: Sei in grado di memorizzare booleani e qualsiasi cosa desideri usando la funzione data() . Non si tratta solo di archi 🙂

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

    E poi si tratta solo di accedere allo stato degli elementi.

    Hai pensato di usare mouseOver e mouseOut per simulare questo. Guarda anche mouseEnter e mouseLeave

    Tieni traccia di entrambi gli stati (al passaggio del mouse, focalizzati) come flag vero / falso, e ogni volta che uno cambia, esegui una funzione che rimuove il bordo se entrambi sono falsi, altrimenti mostra il bordo.

    Quindi: onfocus set focused = true, onblur set focused = false. onmouseover imposta hovered = true, onmouseout imposta hovered = false. Dopo ognuno di questi eventi, esegui una funzione che aggiunge / rimuove il bordo.

    Per quanto ne so, non è ansible chiedere al browser se l’input sullo schermo è focalizzato, è necessario impostare una sorta di tracciamento della messa a fuoco.

    Di solito ho una variabile chiamata “noFocus” e la imposta su true. Quindi aggiungo un evento di messa a fuoco a tutti gli input che rende false false. Quindi aggiungo un evento di sfocatura a tutti gli input che riportano noFocus su true.

    Ho una class MooTools che gestisce questo abbastanza facilmente, sono sicuro che potresti creare un plugin jQuery per fare lo stesso.

    Una volta creato, è ansible controllare noFocus prima di eseguire uno scambio di bordi.

    Non c’è: focus, ma c’è: selezionato http://docs.jquery.com/Selectors/selected

    ma se vuoi cambiare il modo in cui le cose appaiono in base a ciò che è selezionato, probabilmente dovresti lavorare con gli eventi di sfocatura.

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

    C’è un plugin per verificare se un elemento è focalizzato: http://plugins.jquery.com/project/focused

     $('input').each(function(){ if ($(this) == $.focused()) { $(this).addClass('focused'); } }) 

    Ho avuto un evento .live (“focus”) per selezionare () (evidenziare) il contenuto di un input di testo in modo che l’utente non debba selezionarlo prima di digitare un nuovo valore.

    $ (FormObj) .Select ();

    A causa di stranezze tra browser diversi, la selezione a volte sarebbe stata sostituita dal clic che l’aveva provocata, e avrebbe deselezionato i contenuti subito dopo per posizionare il cursore all’interno del campo di testo (ha funzionato principalmente bene in FF ma non è riuscito in IE)

    Pensavo di poter risolvere questo problema mettendo un leggero ritardo sulla selezione …

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

    Questo ha funzionato bene e la selezione sarebbe rimasta, ma è emerso un problema divertente. Se si passa da un campo a un altro, lo stato attivo passa al campo successivo prima della selezione. Dato che selezionare ruba la messa a fuoco, la messa a fuoco tornerà indietro e innescherà un nuovo evento di “messa a fuoco”. Questo è finito in una cascata di input seleziona ballare su tutto lo schermo.

    Una soluzione praticabile sarebbe quella di verificare che il campo abbia ancora il focus prima di eseguire select (), ma come accennato, non c’è un modo semplice per controllare … ho finito per rinunciare a tutta l’evidenziazione automatica, piuttosto che girare quello che dovrebbe essere una singola chiamata jQuery select () in una grande funzione caricata con subroutine …

    se a qualcuno importa c’è un modo molto migliore per catturare l’attenzione ora, $(foo).focus(...)

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

    Quello che ho finito è creare una class arbitraria chiamata .elementhasfocus che viene aggiunta e rimossa all’interno della funzione jQuery focus (). Quando la funzione hover () viene eseguita al passaggio del mouse, verifica la presenza di .elementhasfocus:

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

    Quindi se non ha quella class (leggi: nessun elemento all’interno del div ha focus) il bordo viene rimosso. Altrimenti, non succede nulla.

    Semplice