Rolf B: Funktioniert Load auch mit Javascript?

Beitrag lesen

Hallo Anna,

dein HTML und JS könnte verbessert werden:

  • <figure> und <figcaption> verwenden, du hast eine Abbildung mit Titel
  • ein <div> ist trotzdem sinnvoll, damit Du die Anordnung von Bild und Titel nicht im JavaScript festlegen musst. Eventuell ein <span> statt eines <div> - je nachdem, ob Du ein Inline- oder ein Blockelement als Container für's Bild brauchst.
  • Die id kommt dann an die figure
  • Das Suchen der Elemente ist dann mit getElementById umständlich, querySelector ist bequemer
  • Je nach Aufbau deiner Seite musst Du den Bildcontainer vor dem appendChild löschen. Das geht am einfachsten mit innerHTML="".
  • Den Text "Rotkehlchen" solltest Du aber mittels textContent setzen. Du setzt kein HTML, darum braucht man dafür auch nicht den HTML Parser anzuwerfen.
  • Falls dein JavaScript NICHT Teil einer Funktion ist, sondern frei in einem <script> Element steht, solltest Du es kapseln, damit deine Variablen nicht als "Datenmüll" stehen bleiben. Dazu verwendet man einen Funktionsausdruck.
<figure id="vogelbild">
<div></div>
<figcaption>Vogel wird geladen!</p>
</figure>
let vogelbild = document.querySelector("#vogelbild div");
let titel = document.querySelector("#vogelbild figcaption");
let rotkehlchen = document.createElement("img");

rotkehlchen.addEventListener("load", function(event) {
    titel.textContent = "Rotkehlchen";
});

rotkehlchen.src = "bilder/voegel/rotkehlchen.jpg";
vogelbild.innerHTML = "";    // alten Inhalt löschen
vogelbild.appendChild(rotkehlchen, titel);

Wie macht man einen Funktionsausdruck? Ich baue es schrittweise auf. Du erzeugst eine anonyme Funktion, in der Dein Code steht. Und die rufst Du dann auf. Mit einer temporären Variablen würde das so aussehen:

let dummyFunction = function() {
   // dein Code hier
};
dummyFunction();

Der Trick ist jetzt, die temporäre Variable loszuwerden. Du weißt sicherlich, dass man in JavaScript überall, wo ein Wert erwartet wird, auch einen Ausdruck hinschreiben kann, der diesen Wert ermittelt. Da Funktionen in JavaScript ganz normale Objekte sind, gibt es auch Ausdrücke, deren Wert eine Funktion ist.

Aber ganz so einfach geht's auch nicht, das hat historische Gründe. JavaScript interpretiert das als die klassische Syntax zum Definieren einer Funktion und fällt dann beim abschließenden Aufruf mit () auf die Nase.

function() {
   // dein Code hier
}();
// Uncaught SyntaxError: Function statements require a function name

Klammern zu Hilfe!

(function() {
   // dein Code hier
})();

Es sind absolut verrückt aus, aber es funktioniert. Du erzeugst eine freifliegende Funktion, rufst sie im Fluge auf und lässt sie dann in den Abgrund des Garbage Collectors fallen 😉.

Äh nein - lässt Du nicht wirklich. Weil: Du registrierst ja einen Event Listener. D.h. die innere Funktion des Listeners wird vom DOM referenziert, und der Garbage Collector stellt fest: wird noch gebraucht. Und weil eine Funktion auch immer den Kontext referenziert, in dem sie erzeugt wurde, hat auch deine anonyme Funktion noch jemanden, der sie festhält. Sowas kann bei übermäßigem Einsatz Speicherlecks hervorrufen. Es wäre daher hilfreich, den Eventlistener nach Aufruf zu deregistrieren. Dafür muss man der Eventhandlerfunktion noch einen Arbeitsnamen geben.

(function() {
   let vogelbild = document.querySelector("#vogelbild div");
   let titel = document.querySelector("#vogelbild figcaption");
   let rotkehlchen = document.createElement("img");

   rotkehlchen.addEventListener("load", function handler(event) {
       titel.textContent = "Rotkehlchen";
       rotkehlchen.removeEventListener("load", handler);
   });

rotkehlchen.src = "bilder/voegel/rotkehlchen.jpg";
vogelbild.innerHTML = "";    // alten Inhalt löschen
vogelbild.appendChild(rotkehlchen, titel);
})();

So. Nun ist's sauber 😀.

Es gibt auch eine Variante von addEventListener, die den Handler nach einmaligem Aufruf automatisch deregistriert, aber die funktioniert nicht im Internet Explorer.

Rolf

--
sumpsi - posui - obstruxi