Klemens: JavaScript: Problem mit onClick und getElementById

Hallo zusammen,

ich bin in JavaScript noch recht neu und habe folgendes Problem, bei dem ich einfach keine Lösung finde.

Ich habe eine Bildergalerie. Die Bilder werden der Reihe nach angezeigt und nach dem letzten Bild wird wieder von vorne begonnen. Soweit passt alles. Nun habe ich aber einen Button für "nächstes Bild" hinzugefügt (onClick). Wenn ich ihn anklicke, wird sehr kurz das nächste Bild angezeigt, dann wird aber wieder Bild 1 angezeigt, obwohl die Anzeigedauer bei 10 Sekunden angegeben wurde.

Danke für jeden Tipp! Ich bin auch nicht zu faul um Nachzuschauen, aber ich weiß momentan nicht mehr wo.

Schöne Grüße! Klemens

<input type='image' name='next' src='$bild_vor' width='30' height='30' onClick='danachBild();'>

function danachBild()
  {
  xZaehler++;

  if(xZaehler < xAnzahl_aller_Bilder)
    {
    document.getElementById("Foto01").src = ImageArr[xZaehler];
    setTimeout("danachBild()", Anzeigedauer);
    }
  else
    {
    xZaehler = -1;
    danachBild();
    }
  }
  1. Tach!

    Danke für jeden Tipp! Ich bin auch nicht zu faul um Nachzuschauen, aber ich weiß momentan nicht mehr wo.

    Schau mal in deinen Browser. Der hat eingebaute Entwicklertools, mit dem man unter anderem auch Javascript debuggen kann. Das heißt, man setzt sich einen Breakpoint, läuft dann schrittweise durch den Code und schaut sich dabei die Variableninhalte an. So findet man dann auch Abweichungen zwischen Wunsch und Wirklichkeit.

    Ich kann in deinem Code nicht entdecken, was die Ursache ist, aber der ist auch nicht vollständig. Es fehlen Inititalisierungen von Variablen und die angesprochene ID ist auch nicht im zitierten img-Element enthalten. Aber das hast du vermutlich nur beim Kopieren hierher vergessen.

    dedlfix.

    1. Hallo dedlfix,

      danke, das Entwicklermodul kenn ich. Darin hat es mir auch angezeigt, dass das gewünschte Bild angezeigt wird, nur eben sehr kurz. Anstatt das ausgewählte Bild länger anzuzeigen, ging die Anzeige wieder von vorne los.

      Komisch ist, dass bei der automatischen Anzeige von Bild 1 bis Bild 5 alles super passt: funktion danachBild(). Wenn ich aber über den Button onClick den Wert von xZaehler um eins erhöhe, dann beginnt das ganze von vorne.

      Hier der Platzhalter-Code:

        	  <img id='Foto01' />
      

      Schöne Grüße! Klemens

      1. Tach!

        danke, das Entwicklermodul kenn ich. Darin hat es mir auch angezeigt, dass das gewünschte Bild angezeigt wird, nur eben sehr kurz. Anstatt das ausgewählte Bild länger anzuzeigen, ging die Anzeige wieder von vorne los.

        Was du beschreibst, ist was der Anwender sieht. Du bist an der Stelle aber nicht (nur) der Anwender, sondern der Programmierer. Und da musst du nun schauen, was wirklich passiert, beispielsweise welche Variablen wann welche Inhalte haben. Dazu musst du das Entwicklermodul nicht nur kennen, sondern es auch verwenden. Wenn du die gewonnen Erkenntnisse nicht einordnen kannst, dann präsentiere sie hier. Die Alternative ist, die Statik nicht zu berechnen, sondern die Wände einfach nach Gutdünken hinzustellen, so dass das Haus augenscheinlich steht und nicht einstürzt. Aber dann weißt du immer noch nicht, ob genügend Reserve vorhanden ist, damit sich auf das Dach auch noch ein Vogel setzen kann, ohne dass es einbricht.

        dedlfix.

      2. Hallo Klemens,

        Komisch ist, dass bei der automatischen Anzeige von Bild 1 bis Bild 5 alles super passt: funktion danachBild(). Wenn ich aber über den Button onClick den Wert von xZaehler um eins erhöhe, dann beginnt das ganze von vorne.

        Wahrscheinlich wird es so sein, dass sich dein Bildwechselscript nicht darum schert, was du mit onclick erreichen möchtest.

        on-Attribute zu verwenden, ist übrigens auch etwas aus der Mode gekommen. Verwende stattdessen addEventListener.

        Bis demnächst
        Matthias

        --
        Wenn eine Idee nicht zuerst absurd erscheint, taugt sie nichts. (Albert Einstein)
      3. Hallo dedlfix,

        ich habe ein Problem weniger: Statt einem input habe ich ein img genommen.

        <img src='$bild_vor' onClick='danachBild()'/>

        Jetzt wird das nächste Bild ordentlich angezeigt. Das passt, leider wird dabei nach zwei-drei Mal anklicken die Anzeigedauer immer kleiner?? Das muss ich mir noch anschauen.

        Schöne Grüße! Klemens

        1. Hallo,

          ich habe ein Problem weniger: Statt einem input habe ich ein img genommen.

          <img src='$bild_vor' onClick='danachBild()'/>

          welches Problem hast du damit lösen können? Das dürfte eigentich gar nichts ändern.

          Jetzt wird das nächste Bild ordentlich angezeigt.
          Das passt, leider wird dabei nach zwei-drei Mal anklicken die Anzeigedauer immer kleiner?? Das muss ich mir noch anschauen.

          Warum das so ist, habe ich dir eben erklärt.

          So long,
           Martin

          --
          Logik ist die Theorie, Chaos die Praxis.
        2. Das passt, leider wird dabei nach zwei-drei Mal anklicken die Anzeigedauer immer kleiner?? Das muss ich mir noch anschauen.

          Warum das so ist, hat Martin erklärt. Du setzt bei jedem Klick einen neuen Auftrag an Javascript ab, in 10 sec ein Bild anzuzeigen. Die Aufträge überlappen sich zeitlich.

          Du musst dir also jeden Auftrag merken ...

          var auftrag =  = setTimeout(danachBild, Anzeigedauer); // Start Diaschau
          function danachBild() {
            clearTimeout(auftrag); // bisherigen Auftrag stornieren
            ...
            auftrag = setTimeout(danachBild, Anzeigedauer); // Nächster Auftrag
            ...
          }
          

          ... und den letzten Auftrag vorsorglich löschen (ggf. vorher abfragen, ob ein Auftrag vorliegt).

          Linuchs

          1. Hallo Linuchs,

            danke, das mit dem clearTimeout() muss ich noch genauer ausprobieren. Bisher ohne Erfolg. Aber jetzt ist mir die Vorgehensweise von dieser Funktion klar :)

            Danke für den Hinweis, ich melde mich, wenn ich Erfolg hatte!

            Schöne Grüße! Klemens

  2. Moin,

    Ich habe eine Bildergalerie. Die Bilder werden der Reihe nach angezeigt und nach dem letzten Bild wird wieder von vorne begonnen.

    was heißt das? Es gibt noch ein weiteres Script, das die Bilder ohne Nutzer-Interaktion wechselt? Oder was meinst du mit "der Reihe nach angezeigt"?

    Soweit passt alles. Nun habe ich aber einen Button für "nächstes Bild" hinzugefügt (onClick).

    Tipp: Das Attribut heißt onclick, nicht onClick. HTML ist da allerdings tolerant; XHTML wäre es nicht.

    Wenn ich ihn anklicke, wird sehr kurz das nächste Bild angezeigt, dann wird aber wieder Bild 1 angezeigt, obwohl die Anzeigedauer bei 10 Sekunden angegeben wurde.

    Beim kritischen Anschauen erkenne ich nicht, was da falsch laufen könnte - außer, dass durch das setTimeout() natürlich auch trotz Klick nach einer gewissen Zeit eine automatische Weiterschaltung erfolgt. Ist das so gewollt? Denn jedes Klicken erzeugt auch eine Timeout-Anforderung, die 10s nach dem Klick bearbeitet wird - dreimal kurz hintereinander klicken bewirkt also drei weitere schnelle Bildwechsel 10s später.

    Ich hätte aber ein paar Vorschläge zum "Entmystifizieren". Ich würde in erster Linie das Erhöhen des Zählers und das Prüfen des Grenzwerts (Überlauf) an einer Stelle zusammenziehen, anstatt zwei Ablaufzweige zu bauen, die auf den ersten Blick komplett unterschiedlich aussehen (und der pseudo-rekursive Aufruf macht das Verstehen nicht gerade leichter). Und ich würde zweitens nicht einen String an setTimeout() verfüttern, sondern direkt eine Funktionsreferenz. Dann könnte sich das etwa wie folgt vereinfachen:

        function danachBild()
          {
          xZaehler++;
          if (xZaehler>=xAnzahl_aller_Bilder)
            {
              xZaehler = 0;
            }
    
          document.getElementById("Foto01").src = ImageArr[xZaehler];
          setTimeout(danachBild, Anzeigedauer);
          }
    

    Ich weiß nicht, ob ich mit diesen Vereinfachungen auch schon den Fehler eliminiert habe, ohne es zu merken. Aber zumindest ist es so leichter zu überblicken.

    So long,
     Martin

    --
    Logik ist die Theorie, Chaos die Praxis.
    1. Hallo Martin,

      danke, auch wenn der Code irgendwie einfacher machbar wäre, ich habe es versucht und es ging nicht. Aber einfacher machen kann ich ihn immer noch, sobald er funktioniert. Dann arbeite ich mich zum Minimum durch :)

      Wegen setTimeout (Sting verfüttern), das habe ich nicht ganz verstanden :) Ich arbeite noch daran.

      Aber eines ist mir jetzt klar, vor ich ein anderes setTimeout() setze, muss ich das alte löschen. Hier bin ich noch am rumprobieren. Ich habe da was von clearTimeout gelesen...

      Schöne Grüße! Klemens

  3. Hi,

    befindet sich der button in einem form, das durch den Klick submitted wird?

    cu,
    Andreas a/k/a MudGuard

    1. Hallo Andreas,

      ja, der Code schaut so aus:

      <form name='Buttons'>
      <img name='danach' src='$bild_vor' onClick='danachBild()'/>
      </form>
      

      Es funktioniert schon recht gut. Auch wenn der Code irgendwie einfacher machbar wäre, ich habe es versucht und es ging nicht. Aber einfacher machen kann ich es immer noch, sobald er funktioniert. Dann arbeite ich mich zum Minimum durch :)

      Zwei Probleme sind aber noch da, das zweite ist vielleicht nicht mehr da, wenn ich folgendes gelöst habe.

      Sobald ich mehr als 2 x document.getElementById verwende, hängt das Script. Hier wird das Foto angezeigt/gewechselt. Dann der alte Button unten hell, der aktuelle dunkel.

          document.getElementById("Foto01").src = ImageArr[xZaehler];
          document.getElementById(xZaehler).src = button_dunkel;
          document.getElementById(xZaehlerAlt).src = button_hell;
          setTimeout("danachBild()", Anzeigedauer);
      

      Also das setTimeout wird nicht beachtet. Sobald ich das 3. get... weglasse geht es.

      Schöne Grüße! Klemens