2009-05-22 21 views
6

Nota: ¡Una solución posible solo necesita funcionar en Firefox 3.0, mi aplicación no permite el acceso desde IE! =)¿Cambiar el foco Javascript en el evento onClick?

Tengo un enlace que, al hacer clic, se mostrará una caja de luz para el usuario:

<a href="#" onclick="show_lightbox();return false;">show lightbox</a> 

Mi problema es que cuando se muestra la caja de luz, el foco permanece en el enlace. Entonces, si el usuario presiona las teclas hacia arriba o hacia abajo, termina desplazándose por el documento principal, ¡no por la caja de luz que se muestra!

He tratado de establecer el foco al elemento de caja de luz utilizando un código como éste

function focus_on_lightbox() { 
    document.getElementById('lightbox_content').focus(); 
} 

Esto funciona bien si lo escribo en la consola de Firebug, pero no funcionará si lo incluyo al final del fragmento onclick. Parece que no puedo cambiar el enfoque del enlace del código ejecutado dentro del evento onclick?


- Actualización 1 He intentado algo como esto antes

<a href="#" onclick="show_lightbox();focus_on_lightbox();return false;">show lightbox</a> 

y la función de añadir un poco de salida de depuración He modificado de la siguiente manera

function focus_on_lightbox() { 
    console.log('hihi'); 
    console.log(document.activeElement); 
    document.getElementById('lightbox_content').focus(); 
    console.log(document.activeElement); 
} 

La salida es el siguiente

hihi 
<a onclick="closePopup();lightbox('apartment_detail','11619');focus_on_lightbox();return false;" href="#"> 
<a onclick="closePopup();lightbox('apartment_detail','11619');focus_on_lightbox();return false;" href="#"> 

Entonces, ¿el foco antes de hacer algo estaba en el enlace y después de que traté de cambiar el foco, aún permanecía en el enlace?

No es seguro si importa, pero yo uso Ajax para cargar la caja de luz, de la siguiente

new Ajax.Updater(lightbox_content_id, url, {asynchronous:true, evalScripts:true, onLoading:show_lightbox_loading(), onComplete:focus_on_lightbox() }); 

Traté de ajustar el foco después de que el Ajax completa, sino que también, sin suerte.

¿Qué me estoy perdiendo?


Yo he estado tratando de hacer un trabajo de solución que se sugiere a continuación, tratando de ajustar el enfoque, viendo si tuve éxito marcando document.activeElement, si no, espere 100 milisegundos y vuelve a intentarlo. Si utilizo la siguiente función, que funcionará

function focus_on_lightbox() { 
    var seconds_waited = 0 
    pause(100); 
    var current_focus = document.activeElement 
    while (document.getElementById(lightbox_content_id) != current_focus && seconds_waited < 2000) 
    { 
    document.getElementById(lightbox_content_id).focus(); 
    console.log(document.activeElement); 
    pause(100); 
    current_focus = document.activeElement 
    seconds_waited += 100; 
    } 
} 

Sin embargo, si quito la DECLARACIÓN console.log firebug la depuración, la función deja de funcionar !! No tengo idea de por qué este sería el caso? ¿Por qué la salida de una variable a la consola Firebug afecta el enfoque del clima se mueve al elemento o no? ¿La instrucción console.log afecta el enfoque? tal vez al poner el foco en la ventana de depuración de la consola?

Respuesta

3

Aquí es la función que finalmente funcionó

function focus_on_lightbox(seconds) { 
    var seconds_waited 
    seconds_waited = seconds 
    document.getElementById(lightbox_content_id).focus(); 
    seconds_waited += 100; 

    if (document.getElementById(lightbox_content_id) != document.activeElement && seconds_waited < 2000) 
    setTimeout("focus_on_lightbox(" + seconds_waited + ");", 100); 
    { 
    } 
} 

Así que ¿por qué console.log parece afectar a ajustar el enfoque? Antes de usar esta función para pausar entre intentos de cambiar el enfoque.

function pause(milliseconds) { 
    var dt = new Date(); 
    while ((new Date()) - dt <= milliseconds) { /* Do nothing */ } 
} 

Esto provoca que javascript esté constantemente haciendo algo y creo que no le estaba dando al documento el tiempo para renderizar o actualizar algo. Console.log pareció romper este bloqueo y darle a la página la oportunidad de cambiar su enfoque.

Cuando cambié los enfoques para usar el tiempo de espera para pausar entre intentos, ¡console.log ya no era necesario!

Gracias bmoeskau por señalarme en la dirección correcta.

4

Creo que su problema es llamar a su método de enfoque después de devolver falso. el código debe ser así:

<a href="#" 
    onclick="show_lightbox();focus_on_lightbox();return false;"> 
    show lightbox 
</a> 
+0

si no estaba ocupado editando la publicación original, habría dicho esto. – Triptych

+0

En realidad esa fue una de las primeras cosas que intenté y no funcionó. Editaré la pregunta original con más detalles. – Janak

1

En mi experiencia, se enfocan los problemas a veces pueden ser relacionados con el tiempo (por ejemplo, el enfoque() realiza antes de que el elemento es totalmente listo para ser enfocado). Supongo que el marcado de lightbox se crea dinámicamente cuando se llama a la función show_lightbox?Si ese es el caso usted podría intentar añadir un ligero retardo antes de intentar centrar para ver si esa es la cuestión, algo así como:

setTimeout("focus_on_lightbox();", 10); 
+0

Está bien, la idea de tiempo de espera parece funcionar, pero no resuelve mi problema. Para que funcione, tuve que establecer mi tiempo de espera en 1500, un segundo y medio completo. Esto va a dar a mis usuarios un comportamiento incoherente. ¿Hay alguna forma de probar para ver si un elemento está listo para recibir el enfoque? – Janak

0

Hacer que el elemento de centrarse en sí. En el evento de carga del elemento, establezca un tiempo de espera de unos pocos ms y luego llame a this.focus();

Else try jQuery.

Cuestiones relacionadas