2012-02-17 12 views
51

Sembra che l'evento Sfocatura interrompa il funzionamento del gestore eventi click? Ho una casella combinata in cui le opzioni compaiono solo quando il campo di testo è attivo. La scelta di un collegamento opzione dovrebbe causare un evento.L'evento di sfocatura interrompe il funzionamento dell'evento click?

Ho un esempio violino qui: http://jsfiddle.net/uXq5p/6/

di riprodursi:

  1. Selezionare la casella di testo
  2. I collegamenti vengono visualizzati
  3. Fare clic su un collegamento
  4. La sfocatura si verifica anche ed i collegamenti scompare
  5. nient'altro accade.

Comportamento previsto:

Sul punto 5, dopo il verificarsi sfocatura, lo scatto anche dovrebbe anche allora il fuoco. Come posso farlo?

UPDATE:

Dopo aver giocato con questo per un po ', sembra che qualcuno ha fatto di tutto per evitare un già-verificato clicca evento da essere gestito se un evento di sfocatura rende l'elemento cliccato Un- cliccabile.

Ad esempio:

$('#ShippingGroupListWrapper').css('left','-20px'); 

funziona bene, ma

$('#ShippingGroupListWrapper').css('left','-2000px'); 

impedisce l'evento click.

Questo sembra essere un bug in Firefox, dal momento che rendere un elemento non-cliccabile dovrebbe impedire futuri clic, ma non annullare quelli già verificatisi quando potrebbe essere cliccato.

Altre cose che impediscono l'evento click dalla lavorazione:

$('#ShippingGroupListWrapper').css('z-index','-20'); 
$('#ShippingGroupListWrapper').css('display','none'); 
$('#ShippingGroupListWrapper').css('visibility','hidden'); 
$('#ShippingGroupListWrapper').css('opacity','.5'); 

ho trovato un paio di altre domande su questo sito che stanno avendo problemi simili. Sembrano esserci due soluzioni fluttuanti:

  1. Utilizzare un ritardo. Questo è negativo perché crea una condizione di competizione tra il gestore di eventi occulti e il clic. È anche sciatto.

  2. Utilizzare l'evento mousedown. Ma questa non è una grande soluzione dal momento che clickè l'evento corretto per un collegamento. Il comportamento di mousedown è contro-intuitivo da una prospettiva UX, in particolare dal momento che non è possibile annullare il clic spostando il mouse dall'elemento prima di rilasciare il pulsante.

Posso pensare a qualche altro.

3.Use mouseover e mouseout sul link per abilitare/disabilitare l'evento sfocatura per il campo. Questo non funziona con la tabulazione della tastiera poiché il mouse non è coinvolto.

4. La soluzione migliore sarebbe qualcosa di simile:

$('#ShippingGroup').blur(function() 
{ 
    if($(document.activeElement) == $('.ShippingGroupLinkList')) 
     return; // The element that now has focus is a link, do nothing 
    $('#ShippingGroupListWrapper').css('display','none'); // hide it. 
} 

Purtroppo, $(document.activeElement) sembra tornare sempre l'elemento del corpo, non è quello che è stato fatto clic. Ma forse se ci fosse un modo affidabile per sapere 1. quale elemento ha ora focus o due, quale elemento ha causato la sfocatura (non quale elemento è sfocato) dall'interno del gestore di sfocatura. Inoltre, c'è qualche altro evento (oltre allo mousedown) che spara prima della sfocatura?

+3

Il problema è la sfocatura evento sta sparando prima del click. Poiché la sfocatura nasconde quegli elementi, non si fa clic su nulla. – vcsjones

+1

Non sono sicuro che il problema sia nascosto. Ho provato a impostare l'opacità al 50% invece di nasconderli e l'evento click non si verifica ancora. Si prega di consultare jsfiddle.net/75sgt/1 – Nick

+0

Dopo un'ulteriore sperimentazione, è la nuova inattaccabilità che rende "non cliccabile" retroattivamente un elemento già cliccato. Vedi il mio aggiornamento sopra. – Nick

risposta

68

click trigger evento dopo blur in modo che il collegamento venga nascosto. Invece di click utilizzare mousedown funzionerà.

$('.ShippingGroupLinkList').live("mousedown", function(e) { 
    alert('You wont see me if your cursor was in the text box'); 
}); 

Altra alternativa è quella di avere un po 'di ritardo prima di nascondere i link sul blur evento. Sta a te quale approccio andare per.

Demo

+1

Ritardo, anche se penso che sia disordinato: http://jsfiddle.net/uXq5p/8/ –

+0

Il tuo collegamento demo è rotto. – j08691

+0

@ j08691 - Correzione del collegamento demo, grazie per aver segnalato. – ShankarSangoli

5

Si potrebbe provare a caso invece di clickmousedown.

$('.ShippingGroupLinkList').live("mousedown", function(e) { 
    alert('You wont see me if your cursor was in the text box'); 
}); 

Questo non è chiaramente la soluzione migliore come evento mousedown non si ottiene lo stesso modo per l'utente di un evento click. Sfortunatamente, l'evento blur annullerà anche gli eventi mouseup.

+0

Credo che un mousedown innesca una sfocatura. Un'alternativa sarebbe impedire la propagazione sul mouse e eseguire l'azione su mouseup. –

0

4. La soluzione migliore sarebbe qualcosa di simile:

$('#ShippingGroup').blur(function() 
{ 
    if($(document.activeElement) == $('.ShippingGroupLinkList')) 
     return; // The element that now has focus is a link, do nothing 
    $('#ShippingGroupListWrapper').css('display','none'); // hide it. 
} 

Purtroppo, $ (document.activeElement) sembra tornare sempre l'elemento corpo, non quello che è stato fatto clic. Ma forse se ci fosse un modo affidabile per sapere 1. quale elemento ora ha focus o due, quale elemento ha causato la sfocatura (non quale elemento è sfocato) da all'interno del gestore di sfocatura.

Quello che stai cercando è e.relatedTarget. Pertanto, quando si fa clic sul collegamento, è necessario inserire e.relatedTarget con l'elemento di collegamento, quindi nel gestore della sfocatura è possibile scegliere di non nascondere il contenitore se l'elemento selezionato si trova all'interno del contenitore (o confrontarlo direttamente con il collegamento):

$('#ShippingGroup').blur(function(e) 
{ 
    if(!e.relatedTarget || !e.currentTarget.contains(e.relatedTarget)) { 
    // Alt: (!e.relatedTarget || $(e.relatedTarget) == $('.ShippingGroupLinkList')) 

     $('#ShippingGroupListWrapper').css('display','none'); // hide it. 
    } 
} 

(relatedTarget potrebbero non essere supportate nei browser meno recenti per blur eventi, ma sembra di lavorare in ultima Chrome, Firefox e Safari)

0

Esecuzione di un'azione che dovrebbe accadere su un click su un mousedown è male UX .Invece, che cos'è un efficace click? A mousedown e a mouseup.

Pertanto interrompere la propagazione dell'evento mousedown nel gestore mousedown ed eseguire l'azione nel gestore mouseup.

Un esempio in ReactJS:

<a onMouseDown={e => e.preventDefault()} 
    onMouseUp={() => alert("CLICK")}> 
    Click me! 
</a> 
Problemi correlati