Rolf B: Funktioniert click() nur einmal?

Beitrag lesen

Hallo Nico R.,

ja, genau ist das Problem. Durch deine docReady-Funktion wird die Zuweisung der EventListener an die th Elemente auf den nächsten Tick verschoben, und das ist erst nach dem Aufruf von button1.click().

Wenn Du Abhängigkeiten zwischen Modulen hast, brauchst Du typischerweise ein System zum Management von Modulen.

Die einfachste Möglichkeit ist es natürlich, test1.js am Ende des Body zu laden, so dass Du gar nicht darauf warten musst, ob das DOM fertig ist.

Übrigens lädst Du test1.js synchron. Das bedeutet, dass das DOM niemals auf "complete" oder "interactive" steht und immer der DOMContentLoaded Eventhandler genutzt wird.

Die zweite Möglichkeit, die mit dem Tod des Internet Explorer als allgemeingültig betrachtet werden kann, ist das defer-Attribut. Setze es an beiden Scripten. Sie werden dann in der Reihenfolge, in der die script-Elemente angetroffen wurden, ausgeführt, und zwar NACH dem Ende des DOM Parsers (also nach allen synchronen inline-Scripten) und VOR dem Werfen des DOMContentLoaded Events.

Die dritte Möglichkeit ist, wie gesagt, ein Modulmanagementsystem.

Good News: Dein Browser hat schon eins. Gib deinem inline-Script einfach das Attribut type="module" und lade das test-Script darin mit import. Damit kennt der Browser die Abhängigkeit und sorgt dafür, dass ein Script erst losläuft, wenn die Scripte bereit sind, mit von denen es abhängt.

<script type="module">
   import "./test.js";
   
   const button1 = document.getElementById("button1");
   const th = document.getElementById("th");
   ... etc
</script>

Das ./ vor test.js ist für ECMAScript-Module im Browser unbedingt nötig.

Damit erreichst Du dies:

  • Inline-Script und test.js sind keine regulären Scripte mehr, sondern ECMAScript-Module.
  • Module werden grundsätzlich im strict-mode ausgeführt und grundsätzlich so behandelt, als wäre das defer-Attribut gesetzt
  • import wartet, bis test.js geladen ist und macht erst dann weiter

Allerdings kannst Du in einem Modul keine globalen Variablen mehr setzen, die andere Scripte dann verwenden. Das ist aber kein Fehler, sondern eine Gute Sache™️. Wenn ein Modul Code oder Daten bereitstellen soll, muss es sie exportieren. Ich würde Dich dafür gern auf unser Wiki verweisen, aber ich glaube, da ist noch ein klaffendes ToDo...

Zur Verringerung von Wartezeit kannst Du das inline-Modul in den head setzen. Dann lädt der Browser schonmal die Abhängigkeiten, während das DOM aufgebaut wird. Gestartet wird das Modul erst, wenn das DOM fertig ist.

Rolf

--
sumpsi - posui - obstruxi