Rolf B: Eventhandling und Microtasks

Hallo alle,

ich bin mal wieder am Stöbern und habe eine Unklarheit.

Die Idee der JS Eventloop ist ja: Ein Task, dann die Microtasks, dann Layout/Rendering, dann wieder von vorn.

Jetzt stelle ich mir eine größere Webapplication vor, die abstrakt so aussehen könnte.

<body>
   <div>
      <button>Click</button>
   </div>
</body>

Wenn viel Script im Spiel ist, dann ist es durchaus denkbar, dass auf dem Body ein capture-Eventhandler für click existiert UND ein bubble-Eventhandler. Und auf dem div existiert ebenfalls ein capture-Eventhandler UND ein bubble-Eventhandler. Und auf dem button ist auch noch einer registriert. Es geht nicht drum, ob das sinnvoll ist, es soll nur einen komplexen Maximalfall konstruieren.

Klickt nun jemand den Button, wird das click-Event behandelt. Es wird ein Event-Path für den Button errichtet, entlang dieses Eventpath werden die capturing-Handler aufgerufen, dann der Target-Handler, dann in umgekehrter Reihenfolge die bubble-Handler.

Jeder dieser Handler KÖNNTE Microtasks auslösen und in die Microtask-Queue stellen.

Meine Frage ist nun, wie die Ausführungsreihenfolge ist, und ob das spezifziert ist. Ich habe im Moment nur ein müdes Tablet zur Hand, auf dem Weblabore schlecht laufen und wo es keine Konsole gibt, deshalb kann ich schlecht ausprobieren.

const div = document.querySelector("div"),
      btn = document.querySelector("button");
document.body.addEventListener("click", bodyClickCapture, true);
document.body.addEventListener("click", bodyClickBubble);
div.addEventListener("click", divClickCapture, true);
div.addEventListener("click", divClickBubble);
btn.addEventListener("click", btnClick);

Was soweit klar ist, ist diese Reihenfolge (sofern keiner der Handler in den Mechanismus eingreift, natürlich):

  1. bodyClickCapture - queueMicrotask(f1)
  2. divClickCapture - queueMicrotask(f2)
  3. btnClick - queueMicrotask(f3)
  4. divClickBubble - queueMicrotask(f4)
  5. bodyClickBubble - queueMicrotask(f5)

Was mir nicht klar ist: Ist aus Sicht der Engine jeder dieser Aufrufe ein neuer Task mit einer neuen Layoutphase? Oder laufen sie alle 5 und ERST DANN folgt die Layoutphase?

Was ist, wenn jede dieser 5 Funktionen mit queueMicrotask eine Funktion f1 bis f5 in die Microtask-Queue stellt?

Nach einigem Schmökern in der DOM Spec war meine Erwartung, dass die komplette click-Behandlung ein Task ist. Demnach sollten f1 bis f5 nach bodyClickBubble drankommen. Aber, Versuch macht kluch, und ich habe einen kleinen Versuch machen können, bevor mir jsFiddle auf dem Tablet erst den Run-Button versteckt und dann meinen Code gelöscht hat und ich die Lust verlor... da sah es so aus, als ob f3 nach btnClick laufen würde. Das war Chrome für Android.

Gibt es hier ein deterministisches Verhalten und wo ist es spezifiziert, weiß das jemand?

Rolf

--
sumpsi - posui - obstruxi