Focus () and event order (in pure JavaScript)

I am currently working on a large web project with a complex help system and therefore need a deep understanding of when events are triggered synchronously or asynchronously, respectively.

Actually, I am struggling with the focus () method, which I use in many places and which does not seem to work as if it is documented everywhere. I read (some parts) the W3C DOM specs and many articles and tutorials, and they all say the same thing. When we call element.focus (), the following should happen:

1) The cursor (carriage) is installed in the corresponding element.

2) All event handlers that handle the focus event for the corresponding element are called in a synchronous (blocking) manner, that is, it is guaranteed that all these handlers are called before elem.focus () returns. In other words, it is guaranteed that none of these handlers will be called after elem.focus () returns.

When I developed my application, I relied on this behavior, but now it seems that (at least) IE11 and Chrome do not obey these rules. I think I could understand what happens if someone can follow the steps below and answer my last question.

First, consider the following HTML document:

<?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> 

I have parts of the code from here: http://javascript.info/tutorial/events-and-timing-depth . The author uses this code to prove that elem.focus () really works synchronously. To keep things simple, let us use IE11 to show my problem.

Download the HTML document as shown above in IE11. Then click anywhere in the white area of ​​the page to get focus from text input, and then click reload. You should now have a document just loaded with unfocused text input.

Now, when you click the button, you will get three warnings: in onclick, onfocus, out onclick (in that order). This seems to prove that elem.focus () behaves synchronously.

Now consider the following HTML document:

 <?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> 

This is the same document as the first, with the following exception: I replaced alert () with console.log ().

Now download this document in IE11 and open the IE11 console. Again, distract the focus from entering text and reload the document, then press the button. Now the console displays the following lines (in that order):

  in onclick
 out onclick
 onfocus

This seems to prove that the call to elem.focus () is asynchronous (the focus handler is explicitly called after the elem.focus () element is returned), and this is a big problem for my application.

Can someone explain to me exactly why elem.focus () seems synchronous in the first document, but asynchronous in the second?

By the way, I use IE11 here because I managed to find the example above that is very easy to understand. I hope that someone will give a general answer to my question and that they do not tell me that this is just the wrong behavior of IE11.

Firefox seems to be the only browser that does this correctly; Chrome doesn't even work with the first document. I already knew that browsers did not obey the DOM specifications, because in many cases the order of events and the order in which event handlers are called are incorrect. But I was sure (so far) that at least the methods that are indicated as blocking are indeed called synchronously ...

+5
source share

Source: https://habr.com/ru/post/1242941/


All Articles