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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top