2011-08-17 22 views
14

Questo è stato richiesto here prima, ma diversi anni fa, e al momento non esisteva una soluzione multipiattaforma (a parte la soluzione setTimeout, che in realtà non è molto utile).Come determinare dove è stata messa a fuoco?

Mi piacerebbe fare onblur="foo(parm);" e avere foo essere in grado di determinare quale elemento ha ora lo stato attivo.

Sto usando javascript regolare; no jQuery per questo, per favore.

È possibile in questi giorni?

+0

Beh, è ​​possibile farlo in jQuery, il che significa che è fattibile in Javascript. Non ho idea però, bella domanda. +1 –

+0

Hmmm. Puoi pubblicare jQuery in una risposta e forse posso lavorare a ritroso? –

+0

possibile duplicato di [Quando si verifica onblur, come posso scoprire quale elemento è stato attivato da fuoco * a *?] (Http://stackoverflow.com/questions/121499/when-onblur-occurs-how-can-i-find- out-which-element-focus-went-to) –

risposta

7

Si può provare qualcosa di simile:

function whereDidYouGo() { 
    var all = document.getElementsByTagName('*'); 

     for (var i = 0; i < all.length; i++) 
      if (all[i] === all[i].ownerDocument.activeElement) 
       return all[i]; 
} 

EDIT:

function whereDidYouGo() { return document.activeElement; } 
+2

Hmmm. Interessante. Facendo qualche lettura su 'activeElement'. Non sarei in grado di fare 'elementWithFocus = document.activeElement;'? –

+1

@JonathanM: lol, sì, ho appena preso il filtro ': focus' di jQuery – qwertymk

+0

Sì, penso di sì. Questo sembra mostrarlo: http://help.dottoro.com/external/examples/ljmiswgp/activeElement_1.htm –

3

In jQuery, su richiesta del PO:

$(':input').blur(function() { 
    $focusedElement = $(':input:focus'); 
    //Do stuff with $focusedElement 
} 
+1

ha detto di no jquery. –

+0

Grazie, Rikudo. È un punto di partenza. Qualcuno ha idee su come devolvere questo a normale javascript? –

+2

@Daniel: Nei commenti, ho chiesto questo come punto di partenza. È bello –

2

Domanda interessante. Il nocciolo della questione è - quando scocca l'evento "focus", prima o dopo l'evento di sfocatura? Se si attiva prima dell'evento di sfocatura, il problema è semplice, perché è possibile archiviare lo stato attivo in una variabile a cui può accedere l'evento sfocatura.

Tuttavia, almeno in Chrome 13, sembra che l'evento sfocatura si verifichi prima dell'evento di messa a fuoco. Una possibile soluzione.

Dato il seguente codice HTML:

<input id="foo" value='foo' /> 
<input id="bar" value='bar' /> 

È possibile:

var currentFocus; 
var pendingBlur; 

var foo = document.getElementById('foo'); 
foo.addEventListener('focus', function(){ 
    currentFocus = foo; 
    if(pendingBlur !== undefined){ 
     pendingBlur(); 
     pendingBlur = undefined; 
    } 
}); 
foo.addEventListener('blur', function(){ 
    pendingBlur = function(){ 
     console.log('new focus:', currentFocus); 
    }; 
}); 

var bar= document.getElementById('bar'); 
bar.addEventListener('focus', function(){ 
    currentFocus = bar; 
    if(pendingBlur !== undefined){ 
     pendingBlur(); 
     pendingBlur = undefined; 
    } 
}); 
bar.addEventListener('blur', function(){ 
    pendingBlur = function(){ 
     console.log('new focus:', currentFocus); 
    }; 
}); 

Fondamentalmente, io proprio non la richiamata sfocatura quindi è a portata di mano per l'evento di messa a fuoco di chiamare dopo che sappiamo di che elemento è stato focalizzato.

Ecco un working example su JSFiddle.

EDIT: questa soluzione soffre del problema che, se si sfocatura sul form cliccando su qualcosa altro che un altro elemento del modulo, l'evento sfocatura non si attiva mai (visto che attendere l'evento di messa a fuoco). L'unico modo che posso immaginare è l'utilizzo di un timer per controllare se PendingBlur è definito e, in tal caso, chiamarlo. A questo punto non hai più bisogno dell'evento di messa a fuoco per richiamare più il callback della sfocatura ...

+0

Grazie, Matt. Dovrò digerire questo dopo pranzo. :) –

+0

+1 per considerare i tempi di 'blur()' vs. 'focus()' e testarlo su chrome. Tuttavia, un approccio forse migliore per affrontare il ritardo tra 'blur()' e 'focus()' potrebbe essere quello di impiegare un 'setTimeout()' con la funzione chiamata 'onblur'. –

+0

@ Jonathan M, si, sarei propenso a usare un timeout. Ho appena evitato di dare la tua richiesta nella domanda :) – Matt

Problemi correlati