【问题标题】:Why does document.activeElement produce a different result on Mac using Firefox为什么 document.activeElement 在使用 Firefox 的 Mac 上会产生不同的结果
【发布时间】:2019-05-01 11:31:50
【问题描述】:
我有以下代码;
document.addEventListener('submit', function(e) {
e.preventDefault();
console.log(document.activeElement);
});
<form action="/" type="POST">
<label>Enter text: </label><input type="text">
<input type="submit">
</form>
在 Linux 或 Windows(Chrome 或 Firefox)上单击按钮时,控制台中的输出为 <input type="submit">
但是在 Mac Firefox 上,我得到了输出 <body>。 (Chrome 会生成 <input type="submit">
为什么 Mac 版 Firefox 的输出不同?
【问题讨论】:
标签:
javascript
macos
firefox
【解决方案1】:
这听起来确实像一个错误,而您打开 this ticket 时所做的事情是正确的。
如果您的代码绝对需要依赖它,那么一种技巧就是跟踪自己的 activeElement。
:active 伪类已正确设置,因此我们可以利用它来跟踪我们自己的 activeElement。
我们可以在我们试图跟踪的元素上添加一个非常快速的 CSS 过渡,然后监听它们的 transitionend 事件,以便在它们变为或停止活动时进行处理。可以通过检查它们是否与转换结束时的 :active 伪类匹配来检查它们的状态。
然后,当您需要检索document.activeElement 时,您只需首先检查您自己的activeElement 变量是否包含某些内容,否则只能回退到浏览器报告的内容。
另外,由于这个 bug 似乎只影响按钮元素,我们可以只在这些元素上添加这个 hack:
let activeElement;
document.addEventListener('transitionend', function(e) {
// if the target is currently active, it is the activeElement
activeElement = e.target.matches(':active') ? e.target : null;
});
document.addEventListener('submit', function(e) {
e.preventDefault();
// first try to get our own activeElement
// otherwise default to the document's one
console.log('in submit', activeElement || document.activeElement);
});
// to show the default one still works
document.addEventListener('click', function(e) {
console.log('in click', activeElement || document.activeElement);
});
input,button { /* target only buttons UIs */
transition: opacity 0.000001s; /* a really fast transition */
}
input:active,button:active {
opacity: 0.999; /* a property barely noticeable */
}
<form action="/" type="POST">
<label>Enter text: </label><input type="text">
<button type="submit" tabindex="0">submit</button>
</form>
<a href="#">click me</a>