禁用HTML属性中的showModal自动对焦功能

6
据我所知,showModal() 方法执行以下步骤,最终将焦点放在 HTML 对话框内的元素上(强调我的)。
  1. subject为调用该方法的对话框元素。

  2. 如果subject已经有一个打开属性,则抛出"InvalidStateError"DOMException异常。

  3. 如果subject未连接,则抛出"InvalidStateError"DOMException异常。

  4. subject添加一个值为空字符串的打开属性。

  5. 将对话框设置为居中对齐模式。

  6. 使subject节点文档被模态对话框subject阻塞。

  7. 如果subject节点文档顶层尚未包含subject,则subject添加到subject节点文档顶层

  8. 运行subject对话框聚焦步骤

因此,最后一步8将在对话框上运行以下对话框聚焦步骤。从我的理解来看(可能完全错误),规范中的对话框聚焦步骤部分指定了这三个步骤,即仅当元素不是惰性的且可以自动聚焦时,才应聚焦该元素。
  1. 如果主题是inert,则返回。

  2. 让控件成为主题中第一个后代元素,按树顺序排列,不是inert,并且已指定自动对焦属性。

    如果没有这样的元素,则让控件成为主题中第一个非惰性后代元素,按树顺序排列。

    如果也没有这样的元素,则让控件成为主题。

  3. 为控件运行聚焦步骤

    ...

因此,对我来说,如果我的按钮(请参见片段)具有“inert”属性或不可自动聚焦,则在对话框打开时它不应该被聚焦。然而,当我尝试应用这两个属性时,它仍然会被聚焦。
尝试使用inert布尔属性(我认为这会使对话框聚焦步骤返回,从而不进行聚焦):

const dialog = document.querySelector("#dialog");
document.querySelector("#open-btn").addEventListener('click', () => {
  dialog.showModal();
});

document.querySelector("#close-btn").addEventListener('click', () => {
  dialog.close();
});
#close-btn:focus {
  background: red;
}
<button id="open-btn">Open</button>
<dialog id="dialog">
  <button id="close-btn" inert="inert">&times;</button>
</dialog>

尝试将autofocus布尔属性设置为false(我认为这是将其设置为false的方法,我还尝试过autofocus="false",但也无效):

const dialog = document.querySelector("#dialog");
document.querySelector("#open-btn").addEventListener('click', () => {
  dialog.showModal();
});

document.querySelector("#close-btn").addEventListener('click', () => {
  dialog.close();
});
#close-btn:focus {
  background: red;
}
<button id="open-btn">Open</button>
<dialog id="dialog">
  <button id="close-btn" autofocus="">&times;</button>
</dialog>

在这两种方法都无法生效的情况下,我在SO上找到了这个答案,它建议我也可以使用tabindex="-1",但这也没有起作用。

我知道我可以在按钮被聚焦后使用.blur()来模糊按钮,但我的问题具体是:

  1. 为什么上面的两个fiddles不能禁止自动聚焦按钮?
  2. 是否有某种HTML属性可以阻止我的按钮被聚焦?

相关的 GitHub 问题:https://github.com/whatwg/html/issues/1929 - shreyasm-dev
2个回答

0

禁用的元素无法获得焦点。你可以给 close-btn 添加 disabled 属性。

但是,禁用的元素无法被点击。给 open-btn 添加 onclick 属性。将 onclick 设置为: setTimeout(function(){document.getElementById('close-btn').disabled = false})。这将在按钮被点击后的1毫秒内启用按钮。超时是必需的,以免在对话框打开之前就启用了 close-btn

如果对话框重新打开,按钮会自动获得焦点。我们可以给 close-btn 添加另一个 onclick 属性。将 onclick 设置为: this.disabled = true。这将在点击按钮时禁用 close-btn

最终结果:

const dialog = document.querySelector("#dialog");
document.querySelector("#open-btn").addEventListener('click', () => {
  dialog.showModal();
});

document.querySelector("#close-btn").addEventListener('click', () => {
  dialog.close();
});
#close-btn:focus {
  background: red;
}
<button id="open-btn" onclick='setTimeout(function(){document.getElementById("close-btn").disabled = false})'>Open</button>
<dialog id="dialog">
  <button disabled id="close-btn" inert="inert" onclick='this.disabled = true'>&times;</button>
</dialog>


0
也许这个方法会有效,对我来说是有效的。
selectorElement是我们希望在聚焦时不显示轮廓的实际元素时。
selectorElement:focus-visible {
    outline: none;
}

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