提问人:ToneyPK 提问时间:11/6/2023 更新时间:11/6/2023 访问量:39
HTMLDialogElement 在 Chromium 的初始点击时获得关注
HTMLDialogElement gets focus on initial click on Chromium
问:
打开 HTMLDialogElement 后,在它内部的第一次单击也会将对话框元素聚焦到 Chromium 上。基本上,对话框中的每次第一次单击都会触发焦点事件。 在Firefox上并非如此。
在我目前的用例中,对焦陷阱给我带来了问题,但在 FF 上一切都很好。
这是 Chromium 的故意行为吗? 为什么会有区别?
铬行为:
- 第 1 步:按 show()
- 第 2 步:在对话框中单击 -> 焦点事件触发
- 步骤3:单击“对话框外部”,然后再次单击“对话框内”->焦点事件触发
- setp 4:close()
- 第 5 步:showModal()
- 第 6 步:单击任意位置 ->焦点事件触发
FIREFOX 行为:
-
- 从未触发过焦点事件
堆栈闪电战:
https://stackblitz.com/edit/typescript-s7ajm9?file=index.html,index.ts
我将为我当前的用例创建一个解决方法,并将其作为解决方案发布在这里,但问题是是否有理由有不同的行为?
答:
1赞
Keyboard Corporation
11/6/2023
#1
Chromium 和 Firefox 之间的行为差异可能是由于每个浏览器对规范的实现处理焦点的方式。Firefox 可能不会在对话框中第一次单击时触发焦点事件,因为它不会将这种交互视为焦点。但是,Chromium 会触发焦点事件。HTMLDialogElement
为此,您可以尝试在焦点事件侦听器中添加一个条件,以检查事件目标是否为对话框本身。如果是,则可以阻止默认行为。
例;
dialog.addEventListener('focus', (event) => {
if (event.target === dialog) {
event.preventDefault();
} else {
console.warn('The dialog > focus');
}
});
*请注意,浏览器行为可能会有所不同,最好在多个浏览器中测试代码,以确保其行为符合预期。
评论
0赞
ToneyPK
11/6/2023
感谢您的回复。在我的用例中,我有一个位于对话框中的菜单按钮。当我单击菜单按钮时,它会打开一个弹出窗口。在我单击离开(单击对话框/背景)后,弹出窗口关闭,焦点回到菜单按钮上。那是在FF中。但是,Chromium 会中断这种焦点行为,因为我在对话框中单击,并且破坏了预期的行为。
0赞
ToneyPK
11/6/2023
#2
我的用例的工作解决方案:
let lastFocusedElement;
const dialog = document.querySelector('dialog');
const button1 = document.querySelector('#button1');
const button2 = document.querySelector('#button2');
const span = document.querySelector('span');
const handleDialogFocus = (event) => {
if (lastFocusedElement) {
if (event.target === dialog) {
event.preventDefault();
}
lastFocusedElement.focus();
lastFocusedElement = undefined;
}
}
const handleDialogClick = (e) => {
if (!dialog) {
return;
}
const target = e.target;
if (target && (target !== dialog)) {
lastFocusedElement = target;
}
}
const handleButtonClick = () => {
dialog.showModal();
}
const handleButton2Click = () => {
dialog.close();
button1.focus();
}
dialog.addEventListener('focus', handleDialogFocus);
dialog.addEventListener('click', handleDialogClick);
button1.addEventListener('click', handleButtonClick);
button2.addEventListener('click', handleButton2Click);
button:focus {
border: 2px solid red;
}
<dialog>
This is an open modal
<button id="button2">Close and focus back to button</button>
</dialog>
<button id="button1">open modal</button>
评论