2009-05-22 10 views
6

Nota: una possibile soluzione deve funzionare solo in Firefox 3.0, la mia app non consente l'accesso da IE! =)Modifica della messa a fuoco di Javascript nell'evento onClick?

ho un link che, se cliccato, verrà visualizzato un lightbox per l'utente:

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

mio problema è che quando viene visualizzato il lightbox, il focus rimane sul link. Quindi, se l'utente preme i tasti su o giù, finiscono per scorrere il documento principale, non il lightbox che viene visualizzato!

Ho cercato di impostare la messa a fuoco l'elemento lightbox utilizzando il codice come questo

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

Questo funziona bene se digito nella console Firebug, ma non funziona se comprendo che alla fine dello snippet onclick. Sembra come se non riesco a spostare l'attenzione dal collegamento dal codice eseguito all'interno dell'evento onclick?


- Update 1 Ho provato qualcosa di simile prima

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

e ho funzione per aggiungere un po 'di output di debug modificati, come segue

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

L'uscita è il seguente

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="#"> 

Quindi il focus prima di fare qualcosa era sul link e dopo aver provato a cambiare lo stato attivo rimaneva ancora sul link?

Non sono sicuro se è importante, ma io uso ajax per caricare il lightbox, come segue

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

ho cercato di impostare la messa a fuoco dopo l'ajax completo, ma anche, senza fortuna.

Cosa mi manca?


Ho cercato di fare un lavoro di soluzione che è stata suggerita di seguito cercando di impostare la messa a fuoco, vedere se ci sono riuscito controllando document.activeElement, in caso contrario, attendere 100 millisecondi e riprovare. Se uso la seguente funzione, funzionerà

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

Tuttavia, se mi tolgo la statment console.log Firebug il debug, la funzione smette di funzionare !! Non ho idea del perché questo sarebbe il caso ?? Perché l'output di una variabile sulla console di Firebug influisce sul focus del meteo spostato sull'elemento o no? L'istruzione console.log influisce sull'attenzione? forse portando l'attenzione sulla finestra di debug della console?

risposta

3

Qui è la funzione che finalmente ha funzionato

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

Allora perché console.log sembrano influenzare la messa a fuoco? Prima di utilizzare questa funzione per mettere in pausa tra i tentativi di modifica della messa a fuoco.

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

Questo fa sì che Javascript sia costantemente fare qualcosa e penso che non stava dando il tempo per eseguire il rendering del documento o l'aggiornamento o qualcosa del genere. Il console.log sembrava rompere questo blocco e dare alla pagina la possibilità di cambiare il suo focus.

Quando ho cambiato approccio all'utilizzo del timeout per mettere in pausa tra i tentativi, console.log non era più necessario!

Grazie bmoeskau per avermi indicato nella giusta direzione.

4

Penso che il problema sia il metodo di messa a fuoco dopo il ritorno falso. il codice dovrebbe essere così:

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

se non fossi occupato a modificare il post originale, avrei detto questo. – Triptych

+0

In realtà questa è stata una delle prime cose che ho provato e non ha funzionato. Modificherò la domanda originale con maggiori dettagli. – Janak

1

Nella mia esperienza, si concentrano i problemi a volte possono essere relativi alla temporizzazione (ad esempio, messa a fuoco() viene eseguito prima l'elemento è completamente pronto per essere messo a fuoco). Suppongo che il markup lightbox sia creato dinamicamente quando viene chiamata la funzione show_lightbox?Se questo è il caso si potrebbe provare ad aggiungere un leggero ritardo prima di tentare di mettere a fuoco per vedere se questo è il problema, qualcosa di simile:

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

Ok, l'idea di timeout sembra funzionare, ma non risolve il mio problema. Per farlo funzionare dovevo impostare il mio timeout a 1500, un intero secondo e mezzo. Questo darà ai miei utenti un comportamento incoerente. Esiste comunque un test per verificare se un elemento è pronto per ricevere l'attenzione? – Janak

0

Effettuare l'elemento stesso fuoco. Nell'evento load dell'elemento, impostare un timeout di alcuni ms e quindi chiamare this.focus();

Altrimenti prova jQuery.