code21: Stack overflow Fehler? Hat mein Browser Kopfschmerzen oder wie?

Doll habe jetzt das ganze Wochenende an einem Script gebastelt!
(was nich viel zu bedeuten hat, da ich noch viel lernen muss), aber funzt bei meinen kleinen Seiten super.

Setze ich es aber auf größeren Sites ein knallt mir nen Stack overflow Fehler rein. Mein Script hat doch nur zwei var und Endlosschleifen gibt es auch nicht.

funzt aber nur bei IE4/5

<script language="JavaScript">
var x=0;
var i=0;
function finde()
{
  if(document.all.tags("a")[x].contains(document.all.tags("img")[i]))
  {
  alert(document.all.tags("a")[x].outerHTML);
  x=x+1; i=0; alert("Prüfe <a> "+x+" auf <img> "+i); finde();
  }
  else
    {
     if(i+1 < document.all.tags("img").length)
     {
     i=i+1; alert("Prüfe <a> "+x+" auf <img> "+i ); finde();
     }
     else
       { if(x+1 < document.all.tags("a").length)

/*hier irgendwo soll der Fehler sein*/
         {x=x+1; i=0; alert("Nö! kein <img> drin.Prüfe nächstes <a>"); finde();}

else alert("Fertig"); x=0; i=0;
       }
    }
}
</script>

Ach ja ! Gibt es nen guten JavascriptEditor der wohlmöglich auch Jscript erweiterungen von MS schluckt. So mit Quelltextformatierung usw.

PS: Dank an FrankEEE für den letzten Tip! manchmal ist das Brett vorm Kopf halt so groß wie ein Scheunentor...

  1. Hi,

    »»          {x=x+1; i=0; alert("Nö! kein <img> drin.Prüfe nächstes <a>"); finde();}

    Der "Fehler" liegt hier ,)
    Du mußt bei JS aufpassen mit Rekursion, die Engine hat das nicht so
    gern ,)
    Ich hab die Erfahrung gemacht, daß der Stack, abhängig vom RAM,
    so bei 250 Instanzen voll ist.
    Benutz window.setTimeout, da ist der Fehler eigentlich mehr oder
    weniger ausgeschlossen.

    mfg
    CK1

    1. Dank CK1 !

      Tja, das hilft schon mal nen bischen weiter habe es mit dem setTimeout schon probiert

      {setTimeout('x=x+1; i=0; alert("Nö! kein <img> drin.Prüfe nächstes <a>"); finde()', 500);}

      auch an anderen stellen oder mit der ganzen function, doch irgendwie scheine ich das setTimeout falsch zu notieren ...

      Denn setze ich ein setTimeout gibt es ein Problem mit den var ... vieleicht wird der neu Wert nicht übergeben

      oder wird durch ein if{setTimeout("", 500)} else .....
      ..... if übergangen und mit else weitergemacht....??? hmmmm

      Was meint Rekursion bei JS genau....(vieleicht kann ich das Script umschreiben um solch Fehler zu umgehen)???

      P.S. Habe es mittlerweile schon von Stack overflow at line:21 auf 70
      gebracht. aber dafür ist mir jetzt auch schon ganz schlecht!

      1. Hi du da der sich code21 nennt,

        du scheinst nicht zu wissen was Rekursion ist.

        Rekursion tritt dann auf, wenn du in einer Funktion die Funktion selbst wieder aufrufst.

        -------bei dir-----

        function finde()
        {
          if(  )
           {          finde();   }
          .
          .
          .
        }

        -------------------

        Du willst damit erreichen, dass du auch in verschachtelten Tags noch die <img>'s findest.

        Wie CK schon gesagt hat ist bei 250 Rekursionen im IE Schluss. D.h. wenn die Funktion finde() 250mal insich selbst wieder aufgerufen wurde. Wenn du die Funktion hintereinander z.B. in einer for-Schleife aufrufst ist das etwas ganz anderes.

        Rekursion:

        function  finde()
        {
          finde();
        }

        Interation:

        function  finde()
        {

        }

        finde();
        finde();
        finde();
        finde();

        Der IE meckert doch was von wegen "Stack overflow". Der Stack (Stapel) ist der Speicher indem die einzelnen Instanzen der rekursiv aufgerufenen Funktionen abgelegt werden. Dazu gehört der Code der Funktion an sich und alle Variablen und vor allem die Übergabe- und Rückgabeparameter. Das muss gemacht werden, weil bei der Rekursion im Gegensatz zur Interation, wo jede Funktion abgeschlossen wird bevor die nächste aufgerufen wird, die Funktionen noch nicht beendet sind und somit der Rückgabewert der in einer Funktion aufgerufenen Funktion für den weiteren verlauf der selben entscheident ist. Na ja jedenfalls st dieser Speicher begrenzt und ist bei 250 Aufrufen voll. Der NN schafft übrigends 1000 Rekursionen. Man sagt eher der schafft eine Rekursionstiefe von 1000.

        Was musst du jetzt machen:

        Deinen rekursiven Algorithmus in einen interativen umprogrammieren. Falls du damit probleme hast kannst du ja nochmal posten. Es sei nur gesagt, dass sowas _immer_ geht.

        Viel Spass ;-)

        ALEX

      2. Hi code21,

        Was meint Rekursion bei JS genau....

        Eine Funktion ruft sich selber auf.
        Beispiel Fakultät:

        fak(6) = 1*2*3*4*5*6

        "iterative" Lösung
        function fac(x)
        {
          var ergebnis=1;
          for(i=1;i<x;i++)
            ergebnis=ergebnis*i;
          return ergebnis;
        }
        alert(fac(6)); // 720

        "rekursive" Lösung
        function fac(x)
        {
          if(x<=1)
            return 1;
          else
            return x*fac(x-1);
        }
        alert(fac(6)); // auch 720

        Die rekusive Fakultät ist 'programmiertechnisch' eigentlich nicht sinnvoll,
        es ist nur das einfachste Beispiel für Rekursion.
        Der Funktionsparameter (x) ist eine lokale Variable, jeder Aufruf von fac()
        hat seine private Version davon.
        Probier mal fac(100) 1000 10000 -> irgendwann wird der Stack overflow kommen.

        Für Fortgeschrittene gibts dann noch die Türme von Hanoi (->Suchmaschine).

        (vieleicht kann ich das Script umschreiben um solch Fehler zu umgehen)???

        Rekursion per se ist kein Fehler-----------------------^^^^^^

        ansonsten, ja kann man, und zwar 'rein formal' (um mal vorsichtig anzudeuten,
        das ich nicht weiss was das Script machen soll, ich kann kein IE-DHTML)

        <script language="JavaScript">
        var x=0;
        var i=0;
        function finde()
        {
          while(1) // Erstmal Endlosschleife
          {
            if(document.all.tags("a")[x].contains(document.all.tags("img")[i]))
            {
              alert(document.all.tags("a")[x].outerHTML);
              x=x+1;
              i=0;
              alert("Prüfe <a> "+x+" auf <img> "+i);
              // finde();
            }
            else
            {
              if(i+1 < document.all.tags("img").length)
              {
                i=i+1;
                alert("Prüfe <a> "+x+" auf <img> "+i );    
                // finde();
              }
              else
              {
                if(x+1 < document.all.tags("a").length)
                {
                  x=x+1;
                  i=0;
                  alert("Nö! kein <img> drin.Prüfe nächstes <a>");  
                  // finde();
                }
                else
                {
                  alert("Fertig");
                  x=0;
                  i=0;

        break;  // bricht die while(1) Schleife ab
                }
              }
            }
          }
        }

        Jetzt ruft die Funktion finde() sich nicht mehr selbst auf. Das spart
        Resourcen.

        Gruss,
        Carsten

      3. Dank an Carsten und Alex Kiel .... für die ausführliche Hilfe !

        .... den rest werde ich wohl schaffen.

        Wenn das Script fertig ist werde ich es in diesen Thread posten.
        (ich denke so könnte man selbigen zu Ende bringen)

        cu code21