Problem
Sie nutzen jQuery-Code, um ein verborgenes Element anzuzeigen und dessen HTML-Inhalt nach einer Zeitverzögerung zu setzen, die Sie mit setTimeout() erzeugen:
function delayLog(text) { setTimeout( "$(’#log’).show().html(text)", 1000); } // Irgendwo weiter unten im Code delayLog(’Hello’);
Der Aufruf von .show() funktioniert, aber der von .html(text) führt nicht zum gewünschten Ergebnis. Die Firebug-Konsole zeigt, dass die Variable text nicht definiert ist. Der gleiche jQuery-Code funktioniert, wenn er nicht per setTimeout() aufgerufen wird. Gibt es ein Problem, wenn jQuery zusammen mit setTimeout() genutzt wird?
Lösung
Eine Möglichkeit, herauszufinden, ob jQuery die Ursache des Problems ist, ist das Ersetzen Ihres jQuery-Codes durch anderen JavaScript-Code, der kein jQuery verwendet. In diesem Beispiel können wir den jQuery-Code durch ein einfaches alert() austauschen:
function delayLog( text ) { setTimeout( "alert(text)", 1000 ); }
Wenn wir diese Version des Codes auszuprobieren, taucht das gleiche Problem auf – es gibt keinen Alert und Firebug meldet wieder, dass text nicht definiert ist. Damit haben wir das Problem zwar noch nicht gelöst, es aber deutlich eingeschränkt. Es ist ganz offensichtlich nicht jQuery (sofern nicht die reine Existenz der jQuery-Bibliothek auf Ihrer Seite zu einem Problem führt, aber das können Sie herausfinden, indem Sie den
Code auf einer einfachen Testseite laufen lassen, die jQuery nicht einbindet). Also muss etwas am Code selbst falsch sein; sehr wahrscheinlich liegt das Problem beim Umgang mit setTimeout().
Das Problem ist hier tatsächlich, dass ein String-Argument, das man an setTimeout() übergibt, im globalen Gültigkeitsbereich ausgeführt wird – als würde sich der Code außerhalb jeglicher Funktion befinden. Am einfachsten kann man dies lösen, indem man für den Callback anstatt eines Text-Strings eine lokale Funktion nutzt:
function delayLog(text) { setTimeout( function() { alert(text); }, 1000 ); }
Anders als Code in einem String hat eine verschachtelte Funktion vollständigen Zugriff auf die Variablen und Parameter außerhalb der Funktion. So wird dieser Code den Code wie gewünscht ausgeben. Und schließlich hier eine korrigierte Version des ursprünglichen jQuery-Codes:
function delayLog( text ) { setTimeout( function() { $(’#log’).show().html(text); }, 1000 ); }
Diskussion
Wenn Sie debuggen und sich nicht sicher sind, was ein Problem verursacht, kann es helfen, herauszufinden, was das Problem nicht verursacht. Dieses Rezept soll Ihnen nicht dabei helfen, Probleme mit setTimeout() zu lösen – schließlich handelt es sich hier um ein jQuery-Buch, nicht um ein allgemeines JavaScript-Buch – sondern Ihre Debugging-Versuche auf den Kern des Problems zu lenken, indem Sie jQuery als Quelle des Problems zügig ausschließen (oder bestätigen!) können.
Mit diesem und weiteren Rezepten aus dem jQuery Kochbuch lernen Sie praxisbewährte Lösungen von einem Dutzend der führenden Entwickler, die jQuery für wirklich alles einsetzen: von der Integration simpler Komponenten in Webseiten bis hin zur Entwicklung komplexer, hochperformanter User-Schnittstellen.
Und denjenigen, die nur kurz etwas nachschlagen wollen, können wir die kompakte Befehlsreferenz „jQuery – kurz & gut“ ans Herz legen. Es vermittelt dem Leser zu Beginn die notwendigen Grundlagen von JavaScript, dem W3C-Dokumentenmodell und die grundlegende Arbeitsweise mit jQuery. Suchen und Ändern stellen die Kernkapitel der Befehlsreferenz dar und beschreiben die Navigation und Manipulation von DOM-Elementen. Wie man Events und Ajax mit jQuery nutzt und welche Werkzeuge bei der Entwicklung besonders hilfreich sind, sind neben der Anleitung, wie man eigene Plugins erstellt, weitere Kapitel, die dem Leser kurz und präzise die Arbeit mit dem JavaScript-Framework nahe bringen.