2011-02-04 16 views
27

ci sono due elementi in gioco:azione sulla sfocatura tranne quando elemento specifico cliccato con jQuery

$('#myInput') // an input field for search 
$('#myList') // a list to display search results 

voglio nascondere la lista quando l'ingresso non è attivo, in questo modo:

$('#myInput').blur(function() { 
    $('#myList').hide(); 
}); 

Funziona alla grande, tranne quando viene cliccato un elemento della lista, perché l'evento di sfocatura spara e nasconde l'elenco prima che il clic sia registrato. L'obiettivo è che l'elenco rimanga visibile quando si fa clic su qualsiasi parte dell'elenco, anche se ciò causerebbe l'offuscamento dell'input.

Come posso fare questo? Grazie!

risposta

13

È possibile ottenere questo mantenendo una variabile globale, e setTimouts, a attendi un ritardo di 200 ms e poi controlla se uno dei 2 elementi è attivo.

var keepFocus = false; 

function hideList(){ 
    if(!keepFocus){ 
     $('#myList').hide(); 
    } 
} 

$('#myInput').blur(function() { 
    keepFocus = false; 
    window.setTimeout(hideList, 200); 
}).focus(function(){ 
    keepFocus = true; 
}); 


$('#myList').blur(function() { 
    keepFocus = false; 
    window.setTimeout(hideList, 200); 
}).focus(function(){ 
    keepFocus = true; 
}); 
+0

sfocatura e messa a fuoco non sembrano funzionare con #myList poiché non è un input. –

+0

@Justin, che cos'è? Prova a rimuovere il metodo 'focus' sulla lista, e inserisci il codice' sfocato' nel tuo elenco 'click' event –

+0

È solo un div. Ho adattato il tuo codice per funzionare con il mio setup, quindi grazie! –

11

Devi essere in grado di dire "fai questo sfocatura() a meno che la lista non si concentri nello stesso momento".

Questa domanda dice come rilevare se un elemento è attivo: Using jQuery to test if an input has focus

Poi tutto quello che dovete fare è:

$("#myInput").blur(function() { 
    if (!$("#myList").is(":focus")) { 
     $("#myList").hide(); 
    } 
}); 
+4

Non sembra funzionare. document.activeElement mostra il tag body come elemento "focalizzato". Immagino che non funzioni perché l'idea di "focus" è intrinsecamente legata ai campi di input. –

1

Il modo migliore per farlo è quello di collegare un gestore di eventi per l'elemento del corpo, poi un altro gestore per la lista che si ferma la propagazione evento:

$(body).click(function() { 
    $("#myList").hide(); 
}); 

$("#myList").click(function (e) { 
    e.stopImmediatePropagation(); 
}); 

Questa ascolta per un clic al di fuori del # myInput e nasconde #myList. Allo stesso tempo, la seconda funzione ascolta un clic su #myList e se si verifica impedisce l'attivazione di hide().

+4

Questo sta ignorando la tastiera. La sfocatura si attiva quando un campo è escluso. –

7

Ho affrontato lo stesso identico problema, quindi ho risolto il problema.

Mi è venuto in mente che lo blur() scatta prima di click().

Così ho cercato di cambiare click() a mousedown() e abbiamo scoperto che mousedown() incendi prima blur().

E per imitare click() dovrete sparare mousedown() e poi mouseup()

Quindi nel tuo caso vorrei fare qualcosa di simile:

var click_in_process = false; // global 

$('#myList').mousedown(function() { 
    click_in_process = true; 
}); 

$('#myList').mouseup(function() { 
    click_in_process = false; 
    $('#myInput').focus(); 

    // a code of $('#myList') clicking event 

}); 

$('#myInput').blur(function() { 
    if(!click_in_process) { 
     $('#myList').hide(); 

     // a code of what you want to happen after you really left $('#myInput') 

    } 
}); 

Demo/esempio: http://jsfiddle.net/bbrh4/

Speranza aiuta!

+1

Cosa succede se l'ordine degli eventi è diverso in uno specifico browser o dispositivo? Se ricordo correttamente questo ordine non è definito. – Gherman

+1

@German Ha funzionato correttamente in tutti i dispositivi e browser che avevo in quel momento (come ricordo Chrome/Firefox/Opera/IE/iOS/Android/WP). Forse qualcosa è cambiato, ma ad essere onesto ne dubito. Ma se hai in mente qualche esempio specifico, sarò molto felice di saperlo. E se è vero, consiglierei di scrivere un servizio/helper/libreria, dove potresti fare logiche diverse a seconda del browser o del dispositivo corrente. –

+1

Non ho nessun cattivo esempio. Stavo solo diventando più cauto. Teoricamente, l'ordine degli eventi non è definito negli standard. – Gherman

Problemi correlati