Chrome扩展程序 - 弹出窗口中的第一个链接自动聚焦

15

如何停止我的Google Chrome扩展程序的默认操作,使它不自动聚焦在popup.html中第一个链接上?我知道我可以通过一些JS的巧妙处理或更改:focus CSS来解决这个问题,但我认为这可能会影响到我尝试进行的其他操作,并且我更愿意找出根本原因并解决它。

6个回答

16
最简单的(且无需 JavaScript!)方法是向任何不希望自动获得焦点的元素添加 tabindex="-1"

只是一个提示,没有名为“tabindex”的CSS规则,因此您不能使用“a {tabindex:-1}”来设置快捷方式... - Yarco
“tabindex =” -1 “的解决方案不是有点违反UX和可访问性吗?” - sgimeno
2
将选项卡索引设置为-1会从选项卡顺序中删除该元素并阻碍可访问性。我建议避免使用这种技术。 - Ross Allen

5

通过使用具有 tabindex 属性的初始聚焦元素来解决问题可能是最好的方法,具体操作如下:

  • tabindex="-1",如Paul Ferret所建议的,可以防止元素获得焦点
  • tabindex="1",如link0ff所建议的,可以指定应该以焦点开始的元素

如果您的情况更加复杂,希望使用一些 javascript,请参考 link0ff的解决方案。但不要尝试通过定时器来猜测何时模糊,而是监听初始聚焦事件。

function onInitialFocus(event) {
  // Any custom behavior your want to perform when the initial element is focused.

  // For example: If this is an anchor tag, remove focus
  if (event.target.tagName == "A") {
    event.target.blur();
  }

  // ALSO, remove this event listener after it is triggered,
  // so it's not applied to subsequent focus events
  document.removeEventListener("focusin", onInitialFocus);
}

// NOTE: the "focusin" event bubbles up to the document,
// but the "focus" event does not.
document.addEventListener("focusin", onInitialFocus);

我不认为焦点事件是可取消的,因此您不能仅仅抑制该事件。

2
你也可以监听 focus 事件,但是需要使用 addEventListener 的第三个可选参数在捕获阶段而不是冒泡阶段进行监听: document.addEventListener("focus", onInitialFocus, true); - TheMadDeveloper

5

也许自动对焦是为了方便而设计的,但往往会造成不便。由于我看不到停止根本原因的方法,我找到了一些变通方法。其中之一是使用JavaScript。Chrome在显示弹出窗口后短暂延迟后放置自动对焦。可以使用blur()取消对焦,但取消对焦太晚会瞬间闪烁,并且尝试过早取消对焦将无效。因此,在正确的时间取消对焦并不容易,该解决方案尝试在弹出窗口显示后的第一秒内多次执行此操作:

document.addEventListener("DOMContentLoaded", function () {
  var blurTimerId = window.setInterval(function() {
    if (document.activeElement != document.body) {
      document.activeElement.blur();
    }
  }, 200);
  window.setTimeout(function() {
    window.clearInterval(blurTimerId);
  }, 1000);
});

另一个纯HTML方案是在标签上添加tabindex="1"。


1
你应该能够监听初始焦点事件,而不是试图猜测何时可能发生:document.addEventListener("focusin", function() { ... }) ... 不过,在处理程序被调用后,你可能想要删除事件侦听器。有关详细信息,请参见下面的解决方案。 - TheMadDeveloper

4
另一种简单的选择(保留“可制表性”)是在第一个实际链接之前添加一个空链接(<a href="#"></a>)。它会隐形地“捕获”Chrome的自动聚焦,但任何想通过标签浏览链接的用户仍然可以正常操作。
这种方法唯一的小缺点是,在循环时它引入了第二个“死标签”,也就是说,用户需要按三次标签才能从最后一个链接回到第一个链接,而不是两次。

2

tabindex="-1" 对我很有用。我想让一个输入框自动聚焦,但是直到我在输入框之前的每个链接上使用这个属性才起作用。

说实话,这很奇怪。


0

这是解决问题的最佳方案。 tabindex="-1" 的解决方案会损害用户体验,与 @link0ff 的解决方案相反,这个方案会立即移除焦点。

此元素应该是 DOM 中第一个可聚焦的元素:

<button class="invisible-button"></button>

这段代码的作用是在按钮被聚焦后将其移除:
function removeAutoFocus(e) {
    if (e.target.classList.contains("invisible-button")) {
        e.target.style.display = "none";
        document.removeEventListener("focus", removeAutoFocus);
    }
}
document.addEventListener("focus", removeAutoFocus, true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接