d3nn1s: Problem mit window.setTimeout

Hallo zusammen,

ich habe ein Problem mit dem folgenden Code:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Slide Text</title>
<script type="text/javascript">
<!--
function slideText(text, element)
{
 var actTextLength = document.getElementById(element).firstChild.nodeValue.length;
 document.getElementById(element).firstChild.insertData(actTextLength, text);
}

function startTextOutput()
{
 text = 'BalblablablablablaBalblablablablablaBalblablablablabla';
 element = 'content';
 textLength = text.length;
 a = 0;
 while(textLength != a)
 {
  textTemp = text.charAt(a);
  window.setTimeout("slideText(textTemp, element)", 1000);
  a++;
 }
}
//-->
</script>
</head>
<body onload="startTextOutput();">
<div id="content">&nbsp;</div>
</body>
</html>

Ich erwarte eigentlich, dass die Funktion slideText jede Sekunde aufgerufen wird und nach jeder Sekunde einen Buchstaben vom Text (Variable text) hinzufügt bis textLength erreicht ist. Leider ist das Ergebnis komplett anders:
Nach einer Sekunde gibt er folgendes Ergebnis aus:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Jemand eine Idee, was ich da übersehe? Danke für Eure Hilfe bereits im Voraus.

Gruss
Dennis

  1. Hi,

    Jemand eine Idee, was ich da übersehe?

    Lies dir nochmal das SELFHTML-Kapitel zu setTimeout() durch!

    Die Parameterübergabe ist nicht so einfach, wie Du denkst.

    Gruß, Cybaer

    --
    Man muß viel gelernt haben, um über das, was man nicht weiß, fragen zu können.
    (Jean-Jacques Rousseau, Philosoph u. Schriftsteller)
    1. Hi,

      Jemand eine Idee, was ich da übersehe?

      Lies dir nochmal das SELFHTML-Kapitel zu setTimeout() durch!

      Die Parameterübergabe ist nicht so einfach, wie Du denkst.

      Gruß, Cybaer

      Sorry, da steht nicht besonders viel und das habe ich mittlerweile das gefühlte tausendste Mal gelesen. Deine Antwort hilft mir leider nicht sehr viel.

      1. Hi,

        bitte zitiere vernuenftig!

        Sorry, da steht nicht besonders viel und das habe ich mittlerweile das gefühlte tausendste Mal gelesen. Deine Antwort hilft mir leider nicht sehr viel.

        http://aktuell.de.selfhtml.org/artikel/javascript/timer/

        MfG ChrisB

        --
        "The Internet: Technological marvel of marvels - but if you don't know *what* you're lookin' for on the Internet, it is nothing but a time-sucking vortex from hell."
  2. Hallo,

    setTimeout ist kein »an dieser Stelle des Codes solange warten, dann die angegebene Funktion ausführen, dann an der derselben Stelle weitermachen«.

    setTimeout legt einen Timer in den Hintergrund, der nach der gegebenen Zeit aktiv wird, und zwar dann, wenn gerade kein anderer JS-Code ausgeführt wird.

    Wenn du setTimeout mehrfach direkt hintereinander aufrufst, dann führt das nur dazu, dass mehrere Timer im Hintergrund aktiv werden und dann alle zum gleichen Zeitpunkt starten. Und das machst du effektiv in deiner while-Schleife:

    while(textLength != a)
    {
      textTemp = text.charAt(a);
      window.setTimeout("slideText(textTemp, element)", 1000);
      a++;
    }

    Diese while-Schleife läuft in ein paar Millisekunden durch, da der Aufruf von setTimeout nicht die Programmausführung verzögert. Es handelt sich nicht um ein sleep()-Befehl!

    Ich erwarte eigentlich, dass die Funktion slideText jede Sekunde aufgerufen wird und nach jeder Sekunde einen Buchstaben vom Text (Variable text) hinzufügt bis textLength erreicht ist.

    Dann musst du dein Program umstrukturieren. Nicht auf einmal dutzende Timer in den Hintergrund legen, die dann alle zur gleichen Zeit (nämlich 1000 Millisekunden nach Aufruf von setTimeout) aktiv werden. Sondern wirklich zwischen jedem Aufruf von slideText 1000 Millisekunden vergehen lassen.

    Das kannst du z.B. mit http://de.selfhtml.org/javascript/objekte/window.htm#set_interval@title=setInterval umsetzen. Das rufst du einmal auf, dann wird bis zum, Abbruch mit clearInterval alle x Millisekunden eine Funktion aufgerufen. In der kannst du jedes Mal einen weiteren Buchstaben aus dem String entnehmen (dazu brauchst du einen globalen Zähler, wie »a« in deinem jetzigen Code) und ins Dokument schreiben.

    Statt insertData kannst du übrigens auch einfach document.getElementById(element).firstChild.nodeValue += "string"; notieren, soweit ich weiß.

    Mathias