javascript - 为什么 setTimeout(.., 0) 在 Firefox 中的浏览器操作之前触发?漏洞?
问题描述
我有一个input.onkeydown
处理程序,我input.value
在setTimeout(..0)
.
我希望在回调运行input.value
时获得新值。setTimeout
在除 Firefox 之外的所有浏览器中都可以。在 Firefox 中并非总是如此。
要检查的代码是:
<input id="input">
<script>
input.onkeydown = function() {
setTimeout(() => this.value = this.value.toUpperCase());
};
</script>
演示:http ://plnkr.co/edit/rZmiHdttSXNdpKkR8YbH?p=preview
当我在 之后将输入值大写时setTimeout(..0)
,它应该总是大写。但如前所述,在 Firefox 中并非如此。
这是演示视频;前几秒钟证明了问题:https ://jmp.sh/9XSROQ2
相关规范部分是https://dom.spec.whatwg.org/#concept-event-dispatch。
我没有得到什么,还是这是 Firefox 中长期存在的错误?
PS如果我添加console.log
,setTimeout
我有时会看到旧值。
PPS 这个问题的目的是想知道我是否理解setTimeout
正确。我熟悉各种大写的方法input
;请不要建议oninput
, requestAnimationFrame
, 等。
解决方案
实际规格在这里,实际上并没有定义 keydown 和输入当前值变化之间的关系。
不管他们读什么,(强调我的)
对于没有定义输入激活行为但应用了这些事件的输入元素,任何时候用户在没有显式提交操作的情况下导致元素的值发生更改,用户代理必须排队一个任务以在输入元素上触发一个名为 input 的事件,气泡属性初始化为真。当控件失去焦点时,将触发相应的更改事件(如果有)。
因此,实际上指定input
事件(无论如何您都应该听)必须异步触发。由于这个事件是证明当前值发生变化的事件,我不认为 Firefox 在下一个事件循环中应用由 Key 事件引起的变化的行为几乎不是错误;请记住,浏览器必须在事件结束后异步进行此更改(并且不能再被任何处理程序取消)。
一些附加说明(可能与真正的原因有关),输入组合字符(例如^
+ a
=> â
)我在 macOS 上的 FF 中有 100% 的复制(因为是的,我怀疑它也可能与操作系统有关) .
但是,当然,即使它不违反任何规范,并且即使您有一个简单的修复(监听输入事件),您可能仍然希望至少提交一份错误报告,因为它的行为不像其他供应商那样。
推荐阅读
- amazon-web-services - 如何更改 AWS Workspace 组织别名
- django - Django 分页 - NoReverseMatch
- selenium - 如何在移动仿真模式下运行 Selenium Python?
- java - 如何让 jframe 按钮彼此相邻显示?
- google-bigquery - 如何打印通过 Python API 执行的 bigquery 参数化查询?
- css - 如何在右对齐的 div 中左对齐内容?
- sockets - 从 Kubernetes pod 到外部站点的 SSL 套接字连接
- python - 如何在不使用数据库的情况下检索 json?
- react-native - 反应本机 useEffect() 钩子相关
- vue.js - 为什么组件只显示几分之一秒?