我有一个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中的一个长期存在的错误?
P.S。如果我在console.log
中添加setTimeout
,有时会看到旧值。
P.P.S。这个问题的目的是知道我是否正确理解setTimeout
。我熟悉各种大写input
的方式;请不要建议oninput
,requestAnimationFrame
等。
答案 0 :(得分:2)
The actual specs are here,实际上并没有定义按键和输入的当前值的变化之间的关系。
无论他们读什么,(强调我的)
对于没有定义的输入激活行为但适用于这些事件的输入元素,只要用户在没有显式提交动作的情况下使用户的值发生更改,则用户代理must queue a task都会触发名为input的事件在输入元素上,并将bubbles属性初始化为true。如果控件失去焦点,则将触发相应的更改事件。
因此,实际上可以推测input
事件(无论如何都应该监听)必须异步触发。由于此事件是证明当前值发生变化的事件,因此,我认为Firefox在下一个事件循环中应用由Key事件引起的更改的行为几乎不是错误;请记住,事件终止后,浏览器必须异步进行此更改(并且不能再由任何处理程序取消)。
一些附加说明(可能与实际原因有关),输入一个组合字符(例如^
+ a
=> â
),我有100%的复制率FF在macO上(因为是的,我怀疑它也可能与操作系统有关)。
但是,当然,即使它没有违反任何规范,并且即使您有一个简单的修复程序(侦听输入事件),您可能仍要提交错误报告,至少是因为与其他供应商不同
答案 1 :(得分:-1)
我认为是因为Firefox正在处理setTimeout(fn,0)同步,这里也问过:Why does Firefox handle setTimeout(fn, 0) synchronous but setTimeout(fn, 1) asynchronous?
Chrome和节点将0替换为1:Difference between setTimeout(fn, 0) and setTimeout(fn, 1)? 因此,它们始终对他们不同步。 如果使用setTimeout(fn,1)运行它,它也可以在FF中使用。
如果要使其同步,请使用“ oninput”。 “ onkeydown”事件消失后,输入值不会完全更新。 在chrome / ff中使用超时或不超时
input.oninput = function() {
this.value = this.value.toUpperCase()
};