Mudando o foco do JavaScript no evento OnClick?
-
23-08-2019 - |
Pergunta
Nota: Uma solução possível precisa funcionar apenas no Firefox 3.0, meu aplicativo não permite o acesso do IE! =)
Eu tenho um link que, quando clicado, exibirá uma caixa de luz para o usuário:
<a href="#" onclick="show_lightbox();return false;">show lightbox</a>
Meu problema é que, quando a caixa de luz é exibida, o foco permanece no link. Portanto, se o usuário pressionar as teclas para cima ou para baixo, ele acaba rolando o documento principal, não a caixa de luz que é exibida!
Eu tentei definir o foco para o elemento Lightbox usando código como este
function focus_on_lightbox() {
document.getElementById('lightbox_content').focus();
}
Isso funciona bem se eu digitá -lo no console do Firebug, mas não funcionará se eu incluí -lo no final do snippet onclick. Parece que eu não posso mudar o foco do link do código executado dentro do evento OnClick?
- Atualização 1 Eu tentei algo assim antes
<a href="#" onclick="show_lightbox();focus_on_lightbox();return false;">show lightbox</a>
E eu modifiquei a função para adicionar alguma saída de depuração, como segue
function focus_on_lightbox() {
console.log('hihi');
console.log(document.activeElement);
document.getElementById('lightbox_content').focus();
console.log(document.activeElement);
}
A saída é a seguinte
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="#">
Então, o foco antes de fazer algo estava no link e depois que tentei mudar o foco, ele ainda permanecia no link?
Não tenho certeza se isso importa, mas eu uso o Ajax para carregar a caixa de luz, como segue
new Ajax.Updater(lightbox_content_id, url, {asynchronous:true, evalScripts:true, onLoading:show_lightbox_loading(), onComplete:focus_on_lightbox() });
Tentei definir o foco após o Ajax completo, mas também sem sorte.
o que estou perdendo?
Eu tenho tentado fazer um trabalho de solução que foi sugerido abaixo, tentando definir o foco, vendo se consegui verificar o documento.ActiveElement, se não, aguarde 100 milissegundos e tente novamente. Se eu usar a seguinte função, 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;
}
}
No entanto, se eu remover o Firebug Debugging Statment Console.log, a função para de funcionar !! Eu não tenho ideia de por que esse seria o caso? Por que a produção de uma variável para o console do Firebug afetaria o foco climático é movido para o elemento ou não? A declaração do console.log afeta o foco? Talvez trazendo o foco para a janela de depuração do console?
Solução 2
Aqui está a função que finalmente funcionou
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);
{
}
}
Então, por que o console.log pareceu afetar o foco? Antes de eu usar essa função para pausar entre as tentativas de mudar o foco.
function pause(milliseconds) {
var dt = new Date();
while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
}
Isso faz com que o JavaScript esteja constantemente fazendo algo e acho que não estava dando tempo ao documento para renderizar ou atualizar ou algo assim. O console.log parecia quebrar esse bloqueio e dar à página a chance de mudar seu foco.
Quando mudei de abordagens para usar o tempo limite para pausar entre as tentativas, o console.log não era mais necessário!
Obrigado Bmoeskau por me apontar na direção certa.
Outras dicas
Eu acho que seu problema está chamando seu método de foco após o retorno falso. Seu código deve ser assim:
<a href="#"
onclick="show_lightbox();focus_on_lightbox();return false;">
show lightbox
</a>
Na minha experiência, os problemas de foco às vezes podem estar relacionados ao tempo (por exemplo, foco () executados antes que o elemento esteja totalmente pronto para ser focado). Suponho que a marcação da caixa de luz seja criada dinamicamente quando a função Show_lightBox é chamada? Se for esse o caso, você pode tentar adicionar um pequeno atraso antes de tentar se concentrar para ver se esse é o problema, algo como:
setTimeout("focus_on_lightbox();", 10);
Faça o elemento foco em si. No evento de carga do elemento, defina um tempo limite de alguns ms e depois chame isso.focus ();
Caso contrário, tente jQuery.