据我所知,该showModal()方法运行以下步骤,最终将焦点集中在 HTML 对话框中的元素(强调我的):
令subject为调用该方法的对话框元素。
如果主体已经具有开放属性,则抛出“InvalidStateError” DOMException。
如果主体未连接,则抛出 “InvalidStateError” DOMException`。
为subject添加一个open属性,其值为空字符串。
将对话框设置为居中对齐模式。
让主题的节点文档被模式对话框主题遮挡。
运行主题的对话框聚焦步骤。
因此,最后一步8将运行以下对话框,重点关注该对话框上的步骤。根据我的理解(这可能是完全错误的),规范的对话框聚焦步骤部分中的这三个步骤指定仅当元素不是惰性且可自动聚焦时才应聚焦该元素:
因此,对我来说,似乎如果我下面的按钮(参见代码片段)具有该inert属性或不可自动聚焦,那么当对话框打开时它不应该获得焦点。然而,当我尝试应用这两个属性时,它仍然会成为焦点。
尝试使用inert布尔属性(我认为这会使对话框聚焦步骤返回到上面,因此不执行聚焦):
const dialog = document.querySelector("#dialog");
document.querySelector("#open-btn").addEventListener('click', () => {
dialog.showModal();
});
document.querySelector("#close-btn").addEventListener('click', () => {
dialog.close();
});Run Code Online (Sandbox Code Playgroud)
#close-btn:focus {
background: red;
}Run Code Online (Sandbox Code Playgroud)
<button id="open-btn">Open</button>
<dialog id="dialog">
<button id="close-btn" inert="inert">×</button>
</dialog>Run Code Online (Sandbox Code Playgroud)
尝试将autofocus布尔属性设置为 false (我相信这就是将其设置为 false 的方式,我也尝试过,autofocus="false"但也不起作用):
2023 更新:现在使用下面的隐藏代码片段似乎inert确实阻止了按钮自动对焦(当我问这个问题时它没有,我怀疑这是一个 chrome bug),但是它阻止了按钮可点击,所以这是不是一个有效的选项。
const dialog = document.querySelector("#dialog");
document.querySelector("#open-btn").addEventListener('click', () => {
dialog.showModal();
});
document.querySelector("#close-btn").addEventListener('click', () => {
dialog.close();
});Run Code Online (Sandbox Code Playgroud)
#close-btn:focus {
background: red;
}Run Code Online (Sandbox Code Playgroud)
<button id="open-btn">Open</button>
<dialog id="dialog">
<button id="close-btn" autofocus="">×</button>
</dialog>Run Code Online (Sandbox Code Playgroud)
由于这两个都不起作用,我搜索了 SO 并找到了这个答案,这表明我也可以使用tabindex="-1",但这也不起作用。
我知道一旦使用.blur()聚焦按钮,我就可以模糊按钮,但我的问题具体是:
禁用的元素无法获得焦点。您可以将该disabled属性添加到close-btn.
但是,无法单击禁用的元素。添加 onclick 属性到open-btn. 将 设为onclick:setTimeout(function(){document.getElementById('close-btn').disabled = false})。这仅在单击按钮后 1 毫秒启用按钮。close-btn需要超时,以便在打开对话框之前不会启用它。
如果重新打开对话框,该按钮将自动获得焦点。我们可以添加另一个 onclick 属性到close-btn. 设置onclick为close.btn: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();
});Run Code Online (Sandbox Code Playgroud)
#close-btn:focus {
background: red;
}Run Code Online (Sandbox Code Playgroud)
<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'>×</button>
</dialog>Run Code Online (Sandbox Code Playgroud)