6

注意:一个可能的解决方案只需要在 Firefox 3.0 中工作,我的应用程序不允许从 IE 访问!=)

我有一个链接,点击后会向用户显示一个灯箱:

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

我的问题是,当显示灯箱时,焦点仍然在链接上。因此,如果用户按下向上或向下键,他们最终会滚动主文档,而不是显示的灯箱!

我尝试使用这样的代码将焦点设置到灯箱元素

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

如果我在萤火虫控制台中键入它,这很好用,但如果我将它包含在 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 调试语句 console.log,该功能将停止工作!!我不知道为什么会这样??为什么将变量输出到萤火虫控制台会影响天气焦点是否移动到元素?console.log 语句会影响焦点吗?也许通过将焦点带到控制台调试窗口?

4

4 回答 4

4

这是最终起作用的功能

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 为我指明了正确的方向。

于 2009-05-22T07:53:52.543 回答
4

我认为您的问题是在返回 false 后调用您的焦点方法。你的代码应该是这样的:

<a href="#" 
    onclick="show_lightbox();focus_on_lightbox();return false;">
    show lightbox
</a>
于 2009-05-22T05:56:09.677 回答
1

根据我的经验,焦点问题有时可能与时间相关(例如,在元素完全准备好聚焦之前执行 focus())。我假设在调用 show_lightbox 函数时动态创建灯箱标记?如果是这种情况,您可以尝试在尝试集中精力查看是否是问题之前添加一点延迟,例如:

setTimeout("focus_on_lightbox();", 10);
于 2009-05-22T06:26:40.463 回答
0

使元素本身成为焦点。在元素的加载事件上,设置几毫秒的超时,然后调用 this.focus();

否则尝试 jQuery。

于 2009-05-22T07:26:44.157 回答