Bin*_*rus 6 javascript events asynchronous focus synchronous
我目前正在开发一个具有复杂帮助系统的大型Web项目,因此需要深入了解何时同步或异步触发事件.
实际上,我正在使用我在很多地方使用的focus()方法,而且它似乎并不像所有地方都记录的那样工作.我已阅读(某些部分)W3C DOM规范和许多文章和教程,所有这些都说明了相同的内容.当我们调用element.focus()时,应该发生以下情况:
1)光标(插入符号)设置为相应的元素.
2)以同步(阻塞)方式调用处理相应元素的焦点事件的所有事件处理程序,即保证在elem.focus()返回之前调用所有这些处理程序.换句话说,它保证了没有,这些处理器将被称为后 elem.focus()返回.
在开发我的应用程序时,我依赖于这种行为,但现在似乎(至少)IE11和Chrome不遵守这些规则.如果有人能按照以下步骤回答我的最后一个问题,我想我能理解发生了什么.
首先,请考虑以下HTML文档:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
<title>Test</title>
</head>
<body>
<input type="button" value="click me" />
<input type="text" />
<script>
function ButtonHandler(e) {
alert('in onclick')
text.focus()
alert('out onclick')
}
function FieldHandler(e) {
alert('onfocus')
text.onfocus = null
}
var button = document.body.children[0]
var text = document.body.children[1]
button.onclick = ButtonHandler
text.onfocus = FieldHandler
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我从这里获得了部分代码:http://javascript.info/tutorial/events-and-timing-depth.作者使用该代码来证明elem.focus()确实同步工作.为了简单起见,让我们使用IE11来显示我的问题.
请将如上所示的HTML文档加载到IE11中.然后单击页面白色区域的任意位置以获得文本输入的焦点,然后点击重新加载.您现在应该有一个新加载的文档,文本输入未聚焦.
现在,当您单击该按钮时,您将收到三个警报:onclick,onfocus,out onclick(按此顺序).这似乎证明了elem.focus()的行为是同步的.
现在考虑以下HTML文档:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
<title>Test</title>
</head>
<body>
<input type="button" value="click me" />
<input type="text" />
<script>
function ButtonHandler(e) {
console.log('in onclick')
text.focus()
console.log('out onclick')
}
function FieldHandler(e) {
console.log('onfocus')
text.onfocus = null
}
var button = document.body.children[0]
var text = document.body.children[1]
button.onclick = ButtonHandler
text.onfocus = FieldHandler
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
它与第一个文档完全相同,但有以下例外:我已通过console.log()替换了alert().
现在,请将该文档加载到IE11并打开IE11的控制台.再次,将焦点从文本输入中移开并重新加载文档,然后单击按钮.控制台现在显示以下行(按此顺序):
in onclick out onclick onfocus
这似乎证明了对elem.focus()的调用是异步完成的(在 elem.focus()返回后显然调用了焦点处理程序),这对我的应用程序来说是一个很大的问题.
可以请任何人向我解释为什么elem.focus()似乎在第一个文档中是同步的,但在第二个文档中是异步的?
顺便说一句,我在这里使用IE11,因为我已经能够找到上面的例子,这很容易理解.我希望有人会对我的问题给出一般性答案,并且我不会被告知这只是IE11的错误行为.
Firefox似乎是唯一能够做到正确的浏览器,即使使用第一个文档,Chrome也会失败.我已经知道浏览器不遵守DOM规范,因为在许多情况下事件顺序和调用事件处理程序的顺序是错误的.但我一直非常肯定(到现在为止)至少指定为阻塞的方法确实以同步方式调用...