jQuery Events: $(function), ready

jQuery ready: Dokument geladen vs. Dokument mit img, iframe, CSS geladen

jQuery normalisiert das Event Handling zwischen den Browsern und bringt Konsistenz in die Eigenschaften target, relatedTarget, pageX, pageY, which und metaKey. Obwohl die modernen Browser heute das DOM API für Events zuverlässig unterstützen, ist der Umgang mit Events in jQuery einfacher.

Dokument geladen

Drei Events geben im Lebenszyklus einer Webseite den Takt fürs Scripten vor:

DomContentLoaded vs. load
$(function () {
(DOMContentLoaded)
Der Browser hat das HTML vollständig geladen, der DOM-Baum steht, aber externe Ressourcen wie Bilder und Stylesheets sind noch nicht geladen.
$( window ).on("load", handler)
(load)
Der Browser hat das Dokument und alle externen Ressourcen (vor allem alle Bilder) geladen.
$( window ).unload(function()
(beforeunload/unload)
Wenn der Browser die Seite verläßt.

Bevor Script-Anweisungen ausgeführt werden können, müssen die beteiligten Elemente vollständig geladen sein.

Funktioniert nicht
<!DOCTYPE html>
<html>
<head>
    <title>jQuery aufrufen</title>
    <script src="…jquery-3.2.1.min.js"></script>
    <script>
        let length = $("h2").length;
        console.log(length);
    </script>
</head>
<body>
    …
</body>
</html>

Auf die Reihenfolge kommt es an: Zuerst muss das h1-Element geladen sein, erst dann kann jQuery auf das Element zugreifen.

So wird nen Schuh draus
<script asnc src="…jquery-3.2.1.min.js"></script>

<script>
$(function() {
    let length = $("h2").length;
    console.log(length);
});
</script>

Bis das Dokument mit allen Elementen wie Bildern und CSS-Dateien vollständig geladen ist, kann es zu einer sichtbaren Verzögerung beim Start des Skripts kommen. Wenn nur das HTML-Dokument für das Skript erforderlich ist – nicht aber Elemente wie Bilder und Filme –, konnte jQuery dank $(function) schneller starten als reines Javascript. Bevor die Browser DOMContentLoaded auf breiter Basis unterstützen, war der schnelle Eingriff ein großer Vorteil von jQuery gegenüber reinem Javascript.

jQuery 3: $(function ()

Vor jQuery 3 gab es mehrere Versionen des ready-Aufrufs

$(function ()                   // direkt – nicht auf einem individuellen Element

$( document ).ready( handler )  // auf dem document-Element
$( "iframe" ).ready( handler )  // auf in individuelles Element
$().ready( handler )            // auf einem leeren Element

Quelle: .ready()

Diese Varianten sind funktional gleich. Die handler-Funktion wird aufgerufen, sobald das DOM vollständig geladen ist – gleich, auf welchem Element das Event abgerufen wird.

Der Aufruf mit $( "img" ).ready oder $( "iframe" ).ready gegenüber $(document).ready klingt zwar, als würde die Funktion aufgerufen, wenn das Bild geladen wurde — so funktioniert das allerdings nicht. ready feuert, wenn das DOM vollständig geladen ist.

Mit jQuery3 gelten alle Versionen außer $(function () als deprecated - veraltet.

$(function() vs DOMContentLoaded

Dem nativen Javascript (auch als Vanilla Javascript bezeichnet) steht heute ein Event zur Verfügung, mit dem Dom geladen und kann durchquert werden ebenso gut abgerufen werden kann wie mit $(function()DOMContentLoaded.

document.addEventListener ("DOMContentLoaded", function () {
   let length = document.querySelectorAll("h2").length;
   console.log ('DOMContentLoaded ' + length);
});

Allerdings wird die callback-Funktion nicht ausgeführt, wenn das Event bereits gefeuert hat (z.B. durch ein zuvor geladenes externes Script ).

jQuery prüft den readyState-Zustand des Dokuments und führt die callback-Funktion sofort aus.

let callback = function(){
    // Event Handler
};

if ( document.readyState === "complete" ||
    (document.readyState !== "loading" && !document.documentElement.doScroll)) {
    callback();
} else {
    document.addEventListener("DOMContentLoaded", callback);
}

Wann wird .ready() gebraucht?

$(function() wird nur gebraucht, wenn das Script im head-Element der Seite geladen wird.

Wird Script hingegen erst am Ende des body-Elements geladen, sind auch alle Element der Seite sowieso geladen.

Darum werden werden Scripte heute bevorzugt am Ende des HTML-Dokuments vor dem schließenden body-Tag geladen. Dann ist sichergestellt, dass das DOM geladen ist und auf die Elemente zugegriffen werden kann. Ohne $(function() und ohne DOMContentLoaded:

Scripte ans Ende des Dokuments verschieben
<!DOCTYPE html>
<html>
<head>
   <title></title>
</head>
<body>
…
<script asnc src="/dist/jquery-3.2.1.min.js"></script>

<script>
let length = $("h2").length;
console.log ( length );
</script>
</body>

jQuery: Bild asynchron laden

<img class="loading" src="pixel.gif">

pixel.gif ist ein 1px großes gif-Bild. Das CSS für das leere GIF ist

.loading { 
    background: url("loading.gif") 50% no-repeat; 
    width:100%;
    border:1px solid silver 
}

loading.gif ist ein animiertes GIF, ein klassisches Warte-Icon.

Das Bild wird mit jQuery programmatisch erzeugt (let $downloadingImage = $("<img>"). Sobald der Pfad zum Bild notiert ist, beginnt der Ladeprozess und sobald der Ladeprozess beendet ist, feuert das Event.

let $image = $("img.loading");
let $loading = $("<img>");

$loading.on('load', function(){
  $image.attr("src", $(this).attr("src"));
});

$loading.attr("src", "large-elefant.png");

Bild mit Javascript asynchron laden

Das ist kurz und überschaubar. Aber jQuery einbinden, nur weil ein Bild asynchron geladen wird? Heute ist natürliches Javascript ohne Zusatzstoffe genauso weit.

(function () {
let image = document.querySelector(".loading");

let loading = new Image();
loading.onload = function () {
    image.src = this.src; 
}

loading.src = "buffalo.jpg";
})();

Events an ein Element binden

Category: Event Handler Attachment listet die jQuery-Funktionen für das Event Handling. Die wichtigsten sind on() und off(). on() bindet ein Event an die Callback-Funktion, off() entbindet die Callback-Funktion.

$('#test').on("mousemove", onMouseOver);
$('#test').on("click", onMouseKlick);
$('#test').on("mouseleave", onMouseLeave);

function onMouseOver (evt) {
    $('#test').text ( evt.type + " : " + evt.pageX + ' ' + evt.pageY );
}

function onMouseKlick (evt) {
    $('#test').text ( evt.type + " : " + evt.pageX + ' ' + evt.pageY );
    $('#test').off ('mousemove', onMouseOver);
}

function onMouseLeave (evt) {
   $('#test').text ('Raus die Maus');
}

Das Beispiel trackt die Maus-Koordinaten und entbindet bei einem Klick auf das Testfeld den mouseover-Handler. Wenn IE8 und ältere Versionen von Internet Explorer nicht mehr unterstützt werden müssen, ist der Unterschied zum klassischen Javascript-Event-API bei einfachen Beispielen wie hier nicht mehr groß.

Aber jQuery on() kann nicht nur ein Event triggern. Um auf ein weiteres Event mit derselben Funktion zu horchen

$('#test').on("mousemove swipe", onMouseOver);	

Die Events sind einfach durch ein Leerzeichen voneinander getrennt.

jQuery – Events mit preventDefault() unterbinden

Popup mit jQuery

Eine immer wiederkehrende Aufgabe: Beim Klick auf einen Link spielt Javascript zusätzliche Elemente ein – in diesem Beispiel eine größere Version des Bildes ohne das Öffnen eines zusätzlichen Browserfensters. Wenn Javascript nicht aktiviert ist, folgt der Klick dem Link auf konventionelle Weise. Damit die ursprüngliche Aktion – das Folgen des Links – bei aktivem Javascript nicht ausgeführt wird, muss die ursprüngliche Aktion unterbunden werden.


<div>
   <a href="bild.jpg" class="popup">
      <img src="thumbs/bild.jpg" width="250" height="220" alt="bild.jpg" />
   </a>
</div>
…

$('.popup').click (function(event) {
   $(this).parent().prepend('<img src="' + $(this).attr('href') + '" id="popped" />');
   event.preventDefault();
	
   $('img#popped').click(function() {
      $(this).remove();
   });
});

Damit dar eigentlich Ereignis (Folgen des Links) verhindert wird, muss die Funktion 'event' als Parameter übergeben. event.preventDefault() verhindert, dass die ursprüngliche Aktion – dem Link folgen – durchgeführt wird.

Bilder neu laden mit jQuery

GIF-Animation mit jquery starten

Sprite für den sprechenden Rabe von frankes

Damit eine GIF-Animation beim Hovern mit der Maus neu geladen und erneut gestartet wird:

$(function() {
    $(".talk").mouseover(function () {
    	$(this).attr({ src: "talking-rabe.gif" });
    })
});

bind, delegate, die, error,live,load, toggle, unbind, undelegate, unload sind in jQuery Version 3 nicht mehr erwünscht.

blur, change, click, dblclick, dblclick, focus, focusin, focusout, hover, keydown, keypress, keyup, mousedown, mouseenter, mouseleave, mousemove, mouseout, mouseover, mouseup, resize, scroll, select, submit
Auslösen bzw. Zuordnen des Events
event.currentTarget
Das aktuelle DOM-Element innerhalb der bubbling-Phase
event.data
Daten, die der Event-Methode übergeben werden, wenn der aktuelle ausgeführte Event Handler angebunden ist.
event.delegateTarget
Gibt das Element zurück, an das der aktuelle Event Handler gebunden ist.
event.isDefaultPrevented
Gibt zurück, ob event.preventDefault angewiesen ist.
event.isImmediatePropagationStopped
Gibt zurück, ob event.stopImmediatePropagation für das Event-Objekt aufgerufen wurde.
event.isPropagationStopped
Gibt zurück, ob event.stopPropagation für das Event-Objekt aufgerufen wurde.
event.namespace
Gibt des Namespace zum Zeitpunkt des Auslösens zurück.
event.pageX
Gibt die Postion der Maus relativ zum linken Rand des Dokuments zurück.
event.pageY
Gibt die Postion der Maus relativ zum oberen Rand des Dokuments zurück.
event.preventDefault
Verhindert die vorgegebene Aktion des Events.
event.relatedTarget
Gibt das Element zurück, das durch die Bewegung der Maus betreten oder verlassen wurde.
event.result
Enthält den letzten / vorausgehenden Wert, der vom Event Handler zurück gegeben wurde.
event.stopImmediatePropagation
Verhindert, dass andere Event Handler aufgerufen werden.
event.stopPropagation
Verhindert das Aufsteigen (bubbling) des Events, so dass Eltern-Element nicht vom Eintreten des Events benachrichtigt werden.
event.target
Gibt das Event-auslösende Element zurück.
event.timeStamp
Gibt den Zeitpunkt des Eintretens des Events als Millisekunden vom 1.1.1970 zurück.
event.type
Gibt des Typ des Events zurück.
event.which
Gibt die Taste oder den Mausbutton zurück.
off
Entfernt den Event Handler, der mit on zugewiesen wurde
on
Weist dem Element den Event Handler zu
one
Weist den ausgewählten Elementen einen oder mehrere Event Handler zu. Dieser Handler kann dem Element nur einmal pro Element zugewiesen werden.
$.proxy
Nimmt eine existierende Funktion und gibt eine neue mit einem speziellen Kontext zurück
ready
Funktion wird ausgeführt, wenn das DOM vollständig geladen ist.
trigger
Triggert alle Events, die an das gewählte Element gebunden sind.
triggerHandler
Triggert alle Funktionen, die an das Event für das gewählte Element gebunden sind.
DomContentLoaded vs. load DOMContentLoaded $function() load $( window ).on("load", handler) beforeunload/unload $( window ).unload(function()