2011-08-17 16 views
14

Esto se ha preguntado here antes, pero hace varios años, y no había una solución multiplataforma en ese momento (que no sea la solución setTimeout, que realmente no es muy útil).¿Cómo determinar dónde fue el foco?

Me gustaría hacer onblur="foo(parm);" y tener foo poder determinar qué elemento ahora tiene foco.

Estoy usando javascript normal; no jQuery para este, por favor.

¿Es posible hoy en día?

+0

Bueno, es factible en jQuery, lo que significa que es factible en Javascript. No tengo ni idea, buena pregunta. +1 –

+0

Hmmm. ¿Puedes publicar el jQuery en una respuesta y quizás pueda trabajar al revés? –

+0

posible duplicado de [Cuando se produce onblur, ¿cómo puedo averiguar qué foco de elemento fue * a *?] (Http://stackoverflow.com/questions/121499/when-onblur-occurs-how-can-i-find- out-which-element-focus-went-to) –

Respuesta

7

Usted puede intentar algo como esto:

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. Interesante. Haciendo un poco de lectura en 'activeElement'. ¿No podría simplemente hacer 'elementWithFocus = document.activeElement;'? –

+1

@JonathanM: lol, sí, acabo de tomar el filtro ': focus' de jQuery – qwertymk

+0

Sí, creo que sí. Esto parece mostrarlo: http://help.dottoro.com/external/examples/ljmiswgp/activeElement_1.htm –

3

En jQuery, a petición de la OP:

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

dijo que no jquery. –

+0

Gracias, Rikudo. Es un punto de partida. ¿Alguien tiene ideas sobre cómo devolver esto a javascript regular? –

+2

@Daniel: En los comentarios, solicité esto como punto de partida. Es genial. –

2

pregunta interesante. El meollo de la cuestión es: ¿cuándo se dispara el evento de "enfoque", antes o después del evento de desenfoque? Si se dispara antes del evento de desenfoque, el problema es fácil, porque puedes simplemente almacenar el foco actual en una variable a la que tu evento de desenfoque puede acceder.

Sin embargo, al menos en Chrome 13, parece que el evento de desenfoque ocurre antes de el evento de foco. Una posible solución.

Dado el siguiente código HTML:

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

continuación, puede:

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); 
    }; 
}); 

Básicamente, simplemente no la devolución de llamada desenfoque por lo que es muy útil para el evento de foco para llamar después de que sabemos acerca de los cuales elemento fue enfocado.

Aquí hay un working example en JSFiddle.

EDIT: Esta solución presenta el problema de que si falta de definición en el formulario haciendo clic en algo otra que otro elemento de formulario, el evento no se dispara nunca desenfoque (ya que esperar a que el evento de foco). La única forma de evitarlo, que yo pueda concebir, es usar un temporizador para verificar si pendingBlur está definido, y si es así, llamarlo. En ese punto, realmente no necesita el evento de enfoque para llamar a la devolución de llamada borrosa más ...

+0

Gracias, Matt. Tendré que digerir esto después del almuerzo. :) –

+0

+1 para considerar el tiempo de 'blur()' vs. 'focus()' y probarlo en chrome. Sin embargo, un mejor enfoque para lidiar con el desfase entre 'blur()' y 'focus()' puede ser emplear un 'setTimeout()' con la función llamada por 'onblur'. –

+0

@Jonathan M, sí, me inclinaría a usar un tiempo de espera. Simplemente lo evité dada tu solicitud en la pregunta :) – Matt

Cuestiones relacionadas