Менять Javascript Focus в событии onClick? - PullRequest
6 голосов
/ 22 мая 2009

Примечание: возможное решение должно работать только в Firefox 3.0, мое приложение не разрешает доступ из IE! =) * * Тысяча одна

У меня есть ссылка, при нажатии на которую пользователь отобразит лайтбокс:

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

Моя проблема в том, что при отображении лайтбокса фокус остается на ссылке. Поэтому, если пользователь нажимает клавиши «вверх» или «вниз», он в конечном итоге прокручивает основной документ, а не отображаемый лайтбокс!

Я попытался установить фокус на элемент лайтбокса, используя такой код

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

Это прекрасно работает, если я наберу его в консоли firebug, но не будет работать, если я добавлю его в конец фрагмента onclick. Похоже, что я не могу изменить фокус с ссылки, выполненной внутри события onclick?


- Обновление 1 Я пробовал что-то подобное раньше

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

и я изменил функцию, добавив вывод отладочной информации следующим образом

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

Вывод выглядит следующим образом

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

Таким образом, фокус до того, как я что-то сделал, был на ссылке, а после того, как я попытался изменить фокус, он все еще оставался на ссылке?

Не уверен, имеет ли это значение, но я использую ajax для загрузки лайтбокса, как показано ниже

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

Я попытался установить фокус после завершения ajax, но тоже не повезло.

Чего мне не хватает?


Я пытался заставить работать решение, которое было предложено ниже, пытаясь установить фокус, проверяя, удалось ли мне проверить document.activeElement, если нет, подождать 100 миллисекунд и повторить попытку. Если я использую следующую функцию, она будет работать

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

Однако, если я удаляю консольный журнал отладки firebug, функция перестает работать !! Я понятия не имею, почему это будет так ?? Почему вывод переменной в консоль Firebug влияет на погоду, фокус перемещается на элемент или нет? Влияет ли выражение console.log на фокус? возможно, перенеся фокус в окно отладки консоли?

Ответы [ 4 ]

4 голосов
/ 22 мая 2009

Вот функция, которая наконец заработала

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

Так почему console.log, кажется, влияет на настройку фокуса? Раньше я использовал эту функцию для паузы между попытками изменения фокуса.

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

Это заставляет javascript постоянно что-то делать, и я думаю, что он не давал документу время на рендеринг, обновление или что-то в этом роде. Казалось, что console.log сломал эту блокировку и дал странице возможность изменить фокус.

Когда я изменил подходы к использованию тайм-аута для паузы между попытками, console.log больше не был нужен!

Спасибо bmoeskau за то, что указал мне правильное направление.

4 голосов
/ 22 мая 2009

Я думаю, что ваша проблема заключается в вызове метода фокуса после возврата false. ваш код должен быть таким:

<a href="#" 
    onclick="show_lightbox();focus_on_lightbox();return false;">
    show lightbox
</a>
1 голос
/ 22 мая 2009

По моему опыту, проблемы с фокусировкой иногда могут быть связаны со временем (например, focus () выполняется до того, как элемент полностью готов к фокусировке). Я предполагаю, что разметка лайтбокса создается динамически, когда вызывается функция show_lightbox? Если это так, вы можете попробовать добавить небольшую задержку, прежде чем пытаться сосредоточиться, чтобы увидеть, в этом ли проблема, что-то вроде:

setTimeout("focus_on_lightbox();", 10);
0 голосов
/ 22 мая 2009

Заставить элемент фокусироваться сам. В событии загрузки элемента установите время ожидания в несколько мс, а затем вызовите this.focus ();

Иначе попробуйте jQuery.

...