roland: DIV langsam verschwinden lassen und wieder herstellen

Hallo,
ich möchte einen Text der in einem DIV Tag eingeschlossen ist langsam unsichtbar machen und e.v. wieder herstellen per Link.

Allerdings soll das Ganze nicht nur am Internet-Explorer funktionieren sondern auch auf Firefox, NN

Vielen Dank im Voraus

Roland

  1. Lieber roland,

    ich möchte einen Text der in einem DIV Tag eingeschlossen ist langsam unsichtbar machen und e.v. wieder herstellen per Link.

    interessante Sache das...

    Allerdings soll das Ganze nicht nur am Internet-Explorer funktionieren sondern auch auf Firefox, NN

    Sehr löblich. Der IE macht ja bekanntermaßen vieles falsch, sodass es in anderen Browsern dann aber richtig dargestellt wird. Zu dumm nur, wenn der Code für eine fehlerhafte Darstellungsweise erstellt wurde, nicht wahr?

    Vielen Dank im Voraus

    Ach bitteschön! Gern geschehen! Aber Du hast ja nix gewollt, wofür es sich zu danken lohnte...

    Liebe Grüße aus Ellwangen,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. hat jemand eine routine die diese funktion abdeckt?

      Im forum hab ich zwar gesucht aber nicht das passende gefunden.

      mfg
      Roland

      1. @@Roland Hieslmayr:

        hat jemand eine routine die diese funktion abdeckt?

        SELF!

        Mit 'window.setTimeout()' schrittweise 'foo.style.opacity' ändern.

        Live long and prosper,
        Gunnar

        --
        „Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann.“ (Joseph Weizenbaum)
        1. Hi Gunnar!

          Dein Tip ist korrekt - trotzdem würde ich an dieser Stelle eher window.setInterval() und window.clearInterval() verwenden, um die Rekursion zu vermeiden, was für Anfänger evtl. schwieriger ist.

          Grüsse,
          Richard

          1. Dein Tip ist korrekt - trotzdem würde ich an dieser Stelle eher window.setInterval() und window.clearInterval() verwenden, um die Rekursion zu vermeiden, was für Anfänger evtl. schwieriger ist.

            Wo ist da eine Rekursion?

            Struppi.

            1. Hi Struppi!

              Setze function x(){...} die opacity schrittweise hoch/runter.

              => window.settimeout("x("+opnNow+")", 500) ruft ja nun einmalig die Funktion x() nach 500 ms auf; allerdings soll die opacity ja schrittweise geändert werden, , weswegen es intelligent wäre, wenn die Funktion x() ihrerseits am Ende einen (konditionalen) Aufruf der Form window.settimeout("x("+opNow+")", 500) enthielte.

              Wenn aber x() sich selbst aufruft, so nennt man dies gemeinhin einen rekursiven Aufruf, da es eine Abbruchbedingung gibt, ist das ganze eine Rekursion (wenn auch ohne Rückgabe).

              Einfacher ist es doch, wenn man definiert (ohne Werte zu beachten):

              var opNow =0;

              function doSth(){
                (...)
                opNow++;
                if (opNow == 100)
                   window.clearInterval("doSth()");
              }

              function start(){
                window.setInterval("doSth()", 500);
              }

              Grüsse,
              Richard

              1. Lieber ritschmanhard,

                Wenn aber x() sich selbst aufruft, so nennt man dies gemeinhin einen rekursiven Aufruf, da es eine Abbruchbedingung gibt, ist das ganze eine Rekursion (wenn auch ohne Rückgabe).

                ich denke, das muss es nicht sein. Rekursion entsteht tatsächlich erst dann, wenn aus dem Selbstaufruf ein Wert zurückgegeben und weiterverarbeitet wird. Sonst hast Du eine Iteration. Oder liege ich hier falsch?

                window.setTimeout kann keinen Wert zurückliefern, der weiterverarbeitet werden könnte. Anscheinend gibt es eine Zahl zurück, die die Anzahl der übergebenen Parameter darstellt...

                function foo(bar) {  
                    if (bar) {  
                        // tue was mit bar  
                  
                        window.setTimeout(function (bar) {  
                           foo(bar);  
                        }, 500);  
                    }  
                }
                

                Obiges Beispiel iteriert nach meinem Verständnis so oft, bis bar einen Wert annimmt, der das if-Statement mit false beantwortet. Es ist fast das Gleiche wie dieser Code:

                function foo(bar) {  
                    // tue was mit bar  
                }  
                  
                while (bar) {  
                    bar = foo(bar);  
                }
                

                Liebe Grüße aus Ellwangen,

                Felix Riesterer.

                --
                ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
                1. Ich hab jetzt mal den Code hier:

                  wenn ich beim onClick event die id des Bildes angebe dann funktioniert das Ganze, gebe ich allerdings die id des <div> an, dann ist die Funktion nicht mehr gegeben. Was könnte da das Problem sein.

                  Danke Roland

                  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                  <html xmlns="http://www.w3.org/1999/xhtml">
                  <head>
                  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                  <title>Unbenanntes Dokument</title>

                  <script language="javascript" type="text/javascript">

                  function shiftOpacity(id, millisec) {
                   //if an element is invisible, make it visible, else make it ivisible
                   if(document.getElementById(id).style.opacity == 0) {
                    opacity(id, 0, 100, millisec);
                   } else {
                    opacity(id, 100, 0, millisec);
                   }
                  }

                  function opacity(id, opacStart, opacEnd, millisec) {
                   //speed for each frame
                   var speed = Math.round(millisec / 100);
                   var timer = 0;

                  //determine the direction for the blending, if start and end are the same nothing happens
                   if(opacStart > opacEnd) {
                    for(i = opacStart; i >= opacEnd; i--) {
                     setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
                     timer++;
                    }
                   } else if(opacStart < opacEnd) {
                    for(i = opacStart; i <= opacEnd; i++)
                     {
                     setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
                     timer++;
                    }
                   }
                  }

                  function changeOpac(opacity, id) {
                   var object = document.getElementById(id).style;
                   object.opacity = (opacity / 100);
                   object.MozOpacity = (opacity / 100);
                   object.KhtmlOpacity = (opacity / 100);
                   object.filter = "alpha(opacity=" + opacity + ")";
                  }

                  </script>
                  </head>
                  <body>
                  <div id="test"> <img id="test1" src="picture/01.jpg" /></div>

                  <div id="asdf" style="position:absolute; top:100px; left:100px"><a href="#" onclick="shiftOpacity('test', '1000')">show/hide</a> </div>

                  <body>
                  </body>
                  </html>

                2. Hallo Felix,

                  ich denke, das muss es nicht sein. Rekursion entsteht tatsächlich erst dann, wenn aus dem Selbstaufruf ein Wert zurückgegeben und weiterverarbeitet wird.

                  Nein.

                  Sonst hast Du eine Iteration. Oder liege ich hier falsch?

                  Ja.

                  window.setTimeout kann keinen Wert zurückliefern, der weiterverarbeitet werden könnte. Anscheinend gibt es eine Zahl zurück, die die Anzahl der übergebenen Parameter darstellt...

                  function foo(bar) {

                  if (bar) {
                          // tue was mit bar

                  window.setTimeout(function (bar) {
                             foo(bar);
                          }, 500);
                      }
                  }

                    
                  Du rufst in einer Funktion foo die Funktion foo erneut auf. Genau das nennt  
                  man Rekursion. Die Verwendung eines Rückgabewertes ist dafür irrelevant.  
                    
                    
                  Freundliche Grüße  
                    
                  Vinzenz
                  
                  1. function foo(bar) {

                    if (bar) {
                            // tue was mit bar

                    window.setTimeout(function (bar) {
                               foo(bar);
                            }, 500);
                        }
                    }

                    
                    >   
                    > Du rufst in einer Funktion foo die Funktion foo erneut auf. Genau das nennt  
                    > man Rekursion. Die Verwendung eines Rückgabewertes ist dafür irrelevant.  
                      
                    hier wird aber nicht die Funktion aufgerufen.  
                      
                    Struppi.
                    
              2. Wenn aber x() sich selbst aufruft, so nennt man dies gemeinhin einen rekursiven Aufruf, da es eine Abbruchbedingung gibt, ist das ganze eine Rekursion (wenn auch ohne Rückgabe).

                x() ruft sich nicht selbst auf. Die Funktion wird ganz nromal beendet und erst nach dem Timeout wird die Funktion nochmals aufgerufen. Es ist also keine Rekursion.

                Struppi.

                1. Hi Struppi, Felix!

                  Dann frag ich mal so:

                  @ Struppi:
                  Ist denn windows.settimeout("x()",5) ein Funktionsaufruf?
                  => imho Ja.

                  Und was bedingt dieser Funktionsaufruf?
                  => den Funktionsaufruf von x()

                  Ruft x() wieder windows.settimeout auf?
                  => ja, wenn Bedingung xy gegeben ist.

                  => Rekursiver Aufruf mit Abbruchbedingung - das zeitliche Verhalten (dass eine Pause eingelegt wird) ist unerheblich.

                  @Felix:
                  Eine Iteration läge vor, wenn eine Schleife für n Elemente Funktion x() aufrufen würde, also das ganze ungefähr so aussähe:

                  for (curOp=0; curOp<100; curOp++)
                  {
                    x(curOp);
                    sleep(500); //ich weiss, dass es dieses Kommando nicht gibt...
                  }

                  Allerdings ist hierbei, wie wir wissen, das Problem, dass dann Javascript eben nicht die opacity Änderung schrittweise anzeigt, weil kein redraw der Oberfläche in der Ausführung der Schleife ausgelöst wird.

                  @both:
                  http://de.wikipedia.org/wiki/Rekursion, insbesondere die Beispiele auch für Iteration/Rekursion...

                  Grüse,
                  Richard

                  1. Dann frag ich mal so:

                    @ Struppi:
                    Ist denn windows.settimeout("x()",5) ein Funktionsaufruf?
                    => imho Ja.

                    Nein, das ist ene Timeout.

                    Struppi.

                  2. Noch etwas zur Ergänzung:

                    => Rekursiver Aufruf mit Abbruchbedingung - das zeitliche Verhalten (dass eine Pause eingelegt wird) ist unerheblich.

                    Du hast Timeout nicht verstanden, es wird keine Pause eingelegt und das Timeout ist hier sehr wohl von Bedeutung.

                    @both:
                    http://de.wikipedia.org/wiki/Rekursion, insbesondere die Beispiele auch für Iteration/Rekursion...

                    Genau, da wird es schön erklärt, eine Rekursion liegt vor, wenn eine Funktion sich selbst aufruft, dadurch entstehen Bäume oder Ketten, das ist hier aber absolut nicht der Fall.

                    Struppi.

                    1. Hi Struppi!

                      Es ist mir an dieser Stelle offensichtlich nicht möglich, zu erklären, dass es unerheblich ist, wie eine aufgerufene Zwischenfunktion (hier: setTimeout()) funktioniert, solange gilt (kein gültiger Code, nur Pseudocode):

                      var count=0;

                      fkt a()
                      {
                        count++;
                        if (x=true)
                          setTimeout(ptr(a()),2000)
                        //und a() ist hier eben NICHT zwingend zuende:
                        alert("Ich bin die aktuell lebende Rekursionsinstanz: " + count);
                        count--;
                      }

                      fkt setTimeout(fktptr toA, sleepTime)
                      {
                         sleep sleepTime;
                         call toA; //ruft a() erneut auf
                      }

                      Man kann weder leugnen, dass die einzelnen Funktionsaufrufe
                      vor Bestätigung des alerts noch leben, noch, dass ein rekursiver Aufruf erfolgt - es werden immmer mehr alerts, und diese entstehen dadurch, dass a() sich  selbst (über den Umweg setTimeout()) aufruft.

                      Die entstehenden alerts verdeutlichen übrigens die entstehende Kette...

                      Grüsse,
                      Richard

                      1. Hi,

                        var count=0;

                        fkt a()
                        {
                          count++;
                          if (x=true)
                            setTimeout(ptr(a()),2000)
                          //und a() ist hier eben NICHT zwingend zuende:

                        Nein, aber der naechste Aufruf von a ist hier auch noch NICHT passiert.

                        Du hast lediglich die Anweisung, a in x Millisekunden erneut aufzurufen, auf einer Art Stack abgelegt.
                        Der Aufruf erfolgt aber erst spaeter -

                        alert("Ich bin die aktuell lebende Rekursionsinstanz: " + count);
                          count--;
                        }

                        • und zwar erst, wenn das hier abgearbeitet ist.
                          Erst dann kommt der Javascript-Interpreter aus der Abarbeitung von a "zurueck", erst *dann* kuemmert er sich wieder darum, was womoeglich noch auf dem "noch Abzuarbeiten"-Stapel liegt.

                        Man kann weder leugnen, dass die einzelnen Funktionsaufrufe
                        vor Bestätigung des alerts noch leben,

                        Natuerlich nicht - auch damit haeltst du den Interpreter so lange an, bis der Nutzer das Fensterchen bestaetigt hat.

                        noch, dass ein rekursiver Aufruf erfolgt

                        Doch, das kann man sehr gut leugnen, da bin ich der gleichen Ansicht wie Struppi.

                        • es werden immmer mehr alerts, und diese entstehen dadurch, dass a() sich  selbst (über den Umweg setTimeout()) aufruft.

                        Nein.
                        a #1 ist bereits beendet, wenn der Interpreter sich wieder um seinen ToDo-Stack, den du mit setTimeout gefuellt hast, kuemmert. Und erst, wenn er das tut, wird a #2 ausgefuehrt - der Aufruf erfolgt jetzt unabhaengig von a #1, weil das laengst "tot" ist.
                        Das auf-den-Stapel-legen erfolgte aus a #1 heraus - aber der eigentliche *Aufruf* der Instanz a #2 nicht mehr.

                        Die entstehenden alerts verdeutlichen übrigens die entstehende Kette...

                        Die verdeutlichen lediglich eine "Kette" von Funktionsaufrufen, also eine mehrfache Ausfuehrung nacheinander.

                        Die verdeutlichen *keine* Rekursion.
                        Weil, da gehe ich mit Struppi d'accord, keine Rekursion stattfindet.

                        MfG ChrisB

                        1. Du hast lediglich die Anweisung, a in x Millisekunden erneut aufzurufen, auf einer Art Stack abgelegt.

                          nein, im gegenteil bei der Rekursion kommt der stack zur Geltung, hier hast du nur so eine Warteschelife, die in den Interval wenn möglich abgearbeitet wird und soweit ich weiß in JS nich parallel, also jeder Eintrag in der Warteschleife wartet solange bis sein Vorgänger Fertig ist.
                          Das weiß ich aber nicht genau.

                          • und zwar erst, wenn das hier abgearbeitet ist.
                            Erst dann kommt der Javascript-Interpreter aus der Abarbeitung von a "zurueck", erst *dann* kuemmert er sich wieder darum, was womoeglich noch auf dem "noch Abzuarbeiten"-Stapel liegt.

                          kann man so sagen, aber nicht Stapel. Der wird bei der Rekursion erzeugt.

                          Doch, das kann man sehr gut leugnen, da bin ich der gleichen Ansicht wie Struppi.

                          Zu Recht ;-)

                          • es werden immmer mehr alerts, und diese entstehen dadurch, dass a() sich  selbst (über den Umweg setTimeout()) aufruft.

                          Nein.
                          a #1 ist bereits beendet, wenn der Interpreter sich wieder um seinen ToDo-Stack, den du mit setTimeout gefuellt hast, kuemmert. Und erst, wenn er das tut, wird a #2 ausgefuehrt - der Aufruf erfolgt jetzt unabhaengig von a #1, weil das laengst "tot" ist.

                          das ist der entscheidende Unterschied.

                          Die verdeutlichen *keine* Rekursion.
                          Weil, da gehe ich mit Struppi d'accord, keine Rekursion stattfindet.

                          Ich hoffe ich kann ihn mit meinen Beispielen überzeugen.

                          Ansonsten, hat vielleicht noch jemand irgendein Baumskript?
                          Vielleicht der "Rekursiver pythagoreischer Baum" der in Wikipedia genannt wird?

                          Struppi.

                          1. Hi,

                            nein, im gegenteil bei der Rekursion kommt der stack zur Geltung, hier hast du nur so eine Warteschelife, die in den Interval wenn möglich abgearbeitet wird und soweit ich weiß in JS nich parallel, also jeder Eintrag in der Warteschleife wartet solange bis sein Vorgänger Fertig ist.

                            Ja, Stack war hier der falsche Begriff.

                            Davon abgesehen meinte ich es aber genau so, wie du es auch noch mal beschreibst - setTimeout setzt einen Eintrag in eine "Warteliste", und um die wird sich erst dann wieder gekuemmert, wenn die Ausfuehrung des aktuellen Codes beendet wurde.

                            MfG ChrisB

                            1. Hi ChrisB, Struppi!

                              Wie schon vorher:

                              function a()
                              {
                                 window.setTimeout("a()",500);
                                 alert("OK");
                                 return;
                              }
                              a();

                              Ich verstehe schon, worin Ihr den Unterschied seht:

                              Mit window.setTimeout() erfolgt im Prinzip die Anweisung an den Interpreter (main execution process), einen Thread (nebenläufig) zu generieren, was in etwa so aussieht:

                              (*)
                              interpreter -->call                        <---(function a()){
                              interpreter <--callback: generate a Thread <---setTimeout("a()",500);
                              interpreter -->lookup funct.table, find function a() corresponding to "a()"
                              interpreter -->generate thread (a(),500)
                                                             {
                                                                sleep 500;
                                                                call (function a())-->2nd Instance of interpreter, will start at (*)
                                                             }
                              interpreter <--return //from thread generate !not! execute

                              interpreter -->return //from callcack
                              interpreter <--wait for input             <---alert("OK");
                              //sei OK geklickt
                              interpreter -->return to function
                              interpreter <--function a() returns       <---return

                              Es folgt also schematisch, mit [x] als Indikator für die jeweilige Thread-/Interpreterebene (exec folgt aus Funktionsaufruf, genThread folgt aus setTimeout):

                              exec fkt a()[0] -->
                              genThread t[1]-->
                                 t[1] sleep x ms
                                      exec fkt a()[2] -->
                                      genThread t[2]-->
                                         t[2] sleep x ms
                                         exec fkt a()[n] -->
                                         genThread t[n]-->
                                           t[n] sleep x ms
                                           exec fkt a()[n+1] -->
                                           genThread t[n+1]-->...

                              mache weiter mit exec a()[n]
                                      mache weiter mit exec a()[2]
                                 mache weiter mit exec a()[1]
                              mache weiter mit exec a()[0]

                              Wobei für mich hier ersichtlich ist, wo die Rekursion ist, auch wenn durch die Generierung von threads eine Nebenläufigkeit erzeugt ist, die bewirken kann, dass z.B. a[n] vor a[n+1] beendet wird, was evtl. verwirrt.
                              Trotzdem steht innerhalb der Funktion a() eine Anweisung, die das erneute Aufrufen der Funktion a() verursacht (indirekter Selbstaufruf ...). Das ist für mich Rekursion, erzeugt wird eine Kette.

                              Grüsse,
                              Richard

                              1. Hi!

                                Sorry, ein kleiner Fehler hat sich eingeschlichen:

                                Falsch:
                                interpreter -->call                        <---(function a()){
                                Richtig:
                                interpreter -->call                        --->(function a()){

                                Grüsse,
                                Richard

                              2. Wobei für mich hier ersichtlich ist, wo die Rekursion ist, auch wenn durch die Generierung von threads eine Nebenläufigkeit erzeugt ist, die bewirken kann, dass z.B. a[n] vor a[n+1] beendet wird, was evtl. verwirrt.

                                Nicht kann sondern wird. Der timeout Aufruf erfolgt immer nachdem Funktion a() fertig ist, da es wie ich schon erwähnte keine Parallele Abarbeitung in JS erfolgt und selbst wenn, wäre es kein Rekursiveraufruf, den Unterschied habe ich dir ja gezeigt und erklärt. Bei einem Rekursiven Aufruf werden die Variabeln auf den Stack gelegt und sind stehen dem Aufruf wieder zu Verfügung, das ist ein wichtiger Aspekt, der bei deiner These nicht erfüllt ist.

                                Trotzdem steht innerhalb der Funktion a() eine Anweisung, die das erneute Aufrufen der Funktion a() verursacht (indirekter Selbstaufruf ...). Das ist für mich Rekursion, erzeugt wird eine Kette.

                                Nein, wo wird eine Kette erzeugt?
                                Das Beispiel von mir demonstriert doch einwandfrei das es eben keine Kette erzeugt.

                                Struppi.

                                1. Hi Struppi!

                                  Nicht kann sondern wird. Der timeout Aufruf erfolgt immer nachdem Funktion a() fertig ist, da es wie ich schon erwähnte keine Parallele Abarbeitung in JS erfolgt (...)

                                  Stimmt so nicht, Copy und paste Beispiel (*):
                                  schau, wieviele (parallele) alerts du kriegst (vorsicht, Fenster liegen übereinander):

                                  <html>
                                  <head>
                                  <script type="text/javascript">
                                  var count=0;

                                  function a()
                                  {
                                     count++;
                                     if (count<5)
                                        window.setTimeout("a()",2000);
                                     alert ("derzeit laufende Threads:"+count);
                                     count--
                                  }

                                  a();
                                  </script>
                                  </head>
                                  <body>
                                  </body>
                                  </html>

                                  Nach deiner Theorie ja nur einen, weil der timeout vor Beendigung von a() nicht ausgeführt wird und a vor bestätigen des alerts ja nicht beendet wäre. Mein FF generiert 5 alerts in 10 Sekunden...

                                  und selbst wenn, wäre es kein Rekursiveraufruf, den Unterschied habe ich dir ja gezeigt und erklärt. Bei einem Rekursiven Aufruf werden die Variabeln auf den Stack gelegt und sind stehen dem Aufruf wieder zu Verfügung, das ist ein wichtiger Aspekt, der bei deiner These nicht erfüllt ist.

                                  Eine Rekursion benötigt nicht zwingend Variable auf dem Stack:

                                  sei dies "www.foo.bar.undefined":

                                  <html>
                                  <head>
                                  <script>
                                  function (a)
                                  {
                                    var jetzt = new Date();
                                    var name = "w" + getTime());
                                    window.open("www.foo.bar.undefined", name)
                                  }
                                  </script>
                                  </head>
                                  <body>
                                    <p> ich bin eine Instanz </p>
                                  </body>
                                  </html>

                                  ist z.B. auch eine Rekursion.

                                  Nein, wo wird eine Kette erzeugt?

                                  Probier mein Beispiel (*) aus (und denk darüber nach, was ohne if Anweisung passieren würde)...

                                  Grüsse,
                                  Richard

                                  1. Stimmt so nicht, Copy und paste Beispiel (*):
                                    schau, wieviele (parallele) alerts du kriegst (vorsicht, Fenster liegen übereinander):

                                    Du verwechselst einige Dinge, das hat nichts mit Parralell zu tun. Die alert() Fenster gehen auf weil du die Funktion aufrufst ohne dass dort etwas parallel abläuft.

                                    Deutlich was passiert wird es mit diesem Skript:

                                    function a()  
                                    {  
                                       D('start a( '+ ++count +')');  
                                       if (count<5) window.setTimeout("a()",1);  
                                       for(var i = 0; i < 10000; i++) {var x = Math.sin(1);}  
                                       D('ende a( '+ count +')');  
                                    }  
                                      
                                    a();
                                    

                                    Die Schleife dauert garantiert immer länger als 1 Millisekunde, trotzdem werden die Timeouts schön nacheinander abgearbeitet. Keine Spur von Parallele Tätigkeiten.

                                    Nach deiner Theorie ja nur einen, weil der timeout vor Beendigung von a() nicht ausgeführt wird und a vor bestätigen des alerts ja nicht beendet wäre. Mein FF generiert 5 alerts in 10 Sekunden...

                                    Die alerts() sind unabhängig davon, du kannst unzählige alert mit timeout erzeugen.

                                    und selbst wenn, wäre es kein Rekursiveraufruf, den Unterschied habe ich dir ja gezeigt und erklärt. Bei einem Rekursiven Aufruf werden die Variabeln auf den Stack gelegt und sind stehen dem Aufruf wieder zu Verfügung, das ist ein wichtiger Aspekt, der bei deiner These nicht erfüllt ist.

                                    Eine Rekursion benötigt nicht zwingend Variable auf dem Stack:

                                    Doch.

                                    sei dies "www.foo.bar.undefined":

                                    <html>
                                    <head>
                                    <script>
                                    function (a)
                                    {
                                      var jetzt = new Date();
                                      var name = "w" + getTime());
                                      window.open("www.foo.bar.undefined", name)
                                    }
                                    </script>
                                    </head>
                                    <body>
                                      <p> ich bin eine Instanz </p>
                                    </body>
                                    </html>

                                    ist z.B. auch eine Rekursion.

                                    Das stimmt, das ist gewissermaßen ein Rekursiver Aufruf in einem komplexen System, jede Instanz hat einen Vorgänger: opener, darüber kannst du die komplette Kette durchlaufen. Das ist aber in dem Beispiel mit timeout nicht der Fall.

                                    Nein, wo wird eine Kette erzeugt?
                                    Probier mein Beispiel (*) aus (und denk darüber nach, was ohne if Anweisung passieren würde)...

                                    Das ist keine Kette, eine Kette hat Glieder die miteinander verbunden sind und die existieren in dem Beispiel nicht.

                                    Hast du dir die Meldung (im FF) mal angeschaut von

                                    function A() { A();};  
                                    A();
                                    

                                    Dann hast du es schwarz auf weiß. Und jetzt zeig mir eine ähnliche Meldung mit einem Timeout.

                                    Struppi.

                                    1. Hi Struppi!

                                      Du verwechselst einige Dinge, das hat nichts mit Parralell zu tun. Die alert() Fenster gehen auf weil du die Funktion aufrufst ohne dass dort etwas parallel abläuft.

                                      Deutlich was passiert wird es mit diesem Skript:

                                      function a()

                                      {
                                         D('start a( '+ ++count +')');
                                         if (count<5) window.setTimeout("a()",1);
                                         for(var i = 0; i < 10000; i++) {var x = Math.sin(1);}
                                         D('ende a( '+ count +')');
                                      }

                                      a();

                                      
                                      >   
                                      > Die Schleife dauert garantiert immer länger als 1 Millisekunde, trotzdem werden die Timeouts schön nacheinander abgearbeitet. Keine Spur von Parallele Tätigkeiten.  
                                        
                                      Meiner Meinung nach verwechselst du einige Dinge; Dein Beispiel wird nur deshalb "Quasisequenziell" abgearbeitet, da (sei D eine Ausgabefunktion innerhalb des Fensters) die komplette dynamische Aktualisierung (redraw) eines Fensters immer erst nach dem Beenden einer Javascriptfunktion vorgenommen wird.  
                                        
                                      Deshalb werden nach aufruf a()[x] auch immer start[x]/ende[x] quasi zeitgleich ausgegeben (kannst du ja mal prüfen) und dann erst start[x+1]/ende[x+1], auch hier der redraw nach Funktionsende; die Ausgabe erfolgt nach a()[x], weil a()[x+1] später gestartet wurde und die Laufzeit gleich ist.  
                                        
                                      Mein Beispiel war schon korrekt, denn alert() ist normalerweise blockierend, d.h. die Javascriptfunktion hält an der Stelle, an der ein Alert ausgegeben wird, an. Somit müsste (nach deiner Aussage) auch der timeout auf das Bestätigen des Alerts warten, da ja die aufrufende a()[x] Funktion offensichtlich noch nicht beendet ist.  
                                      Dies passiert aber nicht.  
                                        
                                      Ich denke von meiner Seite ist alles dazu gesagt - und ich glaube nicht, dass ich noch weiter was dazu erklären kann.  
                                        
                                      Deshalb nicht böse sein, aber ich zieh mich hiermit aus der Diskussion zurück.  
                                        
                                      Viele Grüsse,  
                                      Richard  
                                        
                                        
                                       
                                      
                                      1. Die Schleife dauert garantiert immer länger als 1 Millisekunde, trotzdem werden die Timeouts schön nacheinander abgearbeitet. Keine Spur von Parallele Tätigkeiten.

                                        Meiner Meinung nach verwechselst du einige Dinge; Dein Beispiel wird nur deshalb "Quasisequenziell" abgearbeitet, da (sei D eine Ausgabefunktion innerhalb des Fensters) die komplette dynamische Aktualisierung (redraw) eines Fensters immer erst nach dem Beenden einer Javascriptfunktion vorgenommen wird.

                                        Aha, auch die Zuweisung einer Eigenschaft? Das ist Unsinn.

                                        Probier doch einfach mal was aus, bevor du etwas behauptest, also hier ein Besispiel, wo nicht direkt in ein Feld geschrieben wird, sondern erst am Schluss:

                                        <textarea rows=10 cols=50 name="out"></textarea>
                                        </form>

                                        <script type="text/javascript" >
                                        var o = document.forms[0].out;
                                        o.value = '';
                                        var debug_txt = '';
                                        function D(txt){
                                         if(!o) return;
                                         debug_txt += txt + '\n';
                                        }

                                        function a()
                                        {
                                           D('start a( '+ ++count +')');
                                           if (count<5) window.setTimeout("a()",1);
                                           else {
                                          // hier sind alle 5 Timeouts fertig.
                                          o.value = debug_txt;
                                         }
                                           for(var i = 0; i < 10000; i++) {var x = Math.sin(1);}
                                           D('ende a( '+ count +')');
                                        }
                                        a();
                                        </script>

                                        Wie du siehst ändert sich gar nichts.

                                        Deshalb werden nach aufruf a()[x] auch immer start[x]/ende[x] quasi zeitgleich ausgegeben (kannst du ja mal prüfen) und dann erst start[x+1]/ende[x+1], auch hier der redraw nach Funktionsende; die Ausgabe erfolgt nach a()[x], weil a()[x+1] später gestartet wurde und die Laufzeit gleich ist.

                                        Dann versuch diese These mal zu beweisen, z.b. in dem du die Laufzeit der Funktionen unterschiedlich lang machst. Übrigens ändert sich nichts am Abluaf, wenn du gar ncihts in der Funktion machst, sie werden sequentiell ausgeführt, immer!

                                        Mein Beispiel war schon korrekt, denn alert() ist normalerweise blockierend,

                                        genau, normalerweise, aber nicht wenn du dieses in einem Timout aufrufst. Dann kannst du, wie schon gesagt, soviel alert() Fenster öffnen wier du willst

                                        d.h. die Javascriptfunktion hält an der Stelle, an der ein Alert ausgegeben wird, an.

                                        Tut es ja, aber die Timeouts werden trotzdem ausgeführt.

                                        Somit müsste (nach deiner Aussage) auch der timeout auf das Bestätigen des Alerts warten, da ja die aufrufende a()[x] Funktion offensichtlich noch nicht beendet ist.

                                        Das habe ich nicht gesagt, der timeout wird immer ausgeführt, aber die Ausführung des weiteren Codes, nach alert(), wird erst nach bestätigen des OK Button ausgeführt. Das kannst du auch leicht nachprüfen, in dem du wahllos in die alert() Fenster wegklickst und dir ausgeben läßt, welche wo das Programm dann weiterläuft.

                                        Ich denke von meiner Seite ist alles dazu gesagt - und ich glaube nicht, dass ich noch weiter was dazu erklären kann.

                                        Du liegst auch falsch.

                                        Deshalb nicht böse sein, aber ich zieh mich hiermit aus der Diskussion zurück.

                                        Ich bin nicht böse, ich konnte hier schön Rekursion erklären und vielleicht hat es der eine oder andere auch verstanden.

                                        Struppi.

                              3. Es folgt also schematisch, mit [x] als Indikator für die jeweilige Thread-/Interpreterebene (exec folgt aus Funktionsaufruf, genThread folgt aus setTimeout):

                                exec fkt a()[0] -->
                                genThread t[1]-->
                                   t[1] sleep x ms
                                        exec fkt a()[2] -->
                                        genThread t[2]-->
                                           t[2] sleep x ms
                                           exec fkt a()[n] -->
                                           genThread t[n]-->
                                             t[n] sleep x ms
                                             exec fkt a()[n+1] -->
                                             genThread t[n+1]-->...

                                mache weiter mit exec a()[n]
                                        mache weiter mit exec a()[2]
                                   mache weiter mit exec a()[1]
                                mache weiter mit exec a()[0]

                                Ich kenne diese Art der schreibweise nicht, aber sie ist falsch. Das passiert nicht.
                                Die aufrufe von a()[>0 .. n] erfolgen nach macheweiter mit exec a().

                                Struppi.

                      2. fkt a()
                        {
                          count++;
                          if (x=true)
                            setTimeout(ptr(a()),2000)
                          //und a() ist hier eben NICHT zwingend zuende:
                          alert("Ich bin die aktuell lebende Rekursionsinstanz: " + count);
                          count--;
                        }

                        Das ist keine Rekursion!

                        fkt setTimeout(fktptr toA, sleepTime)
                        {
                           sleep sleepTime;
                           call toA; //ruft a() erneut auf
                        }

                        Das ist eine.

                        Man kann weder leugnen, dass die einzelnen Funktionsaufrufe
                        vor Bestätigung des alerts noch leben, noch, dass ein rekursiver Aufruf erfolgt - es werden immmer mehr alerts, und diese entstehen dadurch, dass a() sich  selbst (über den Umweg setTimeout()) aufruft.

                        genau wie
                        while(1) { alert('');

                        Eine Rekursion ist es wenn die Funktion in ihrem eigenen Gültigkeitsbereich sich selbst aufruft. Dadruch werden alle lokalen Variabeln auf den Stack geschoben und nach dem Aufruf Der Funktion geht es weiter. Deshalb kommt es ab einer bestimmten Tiefe der Rekursion auch zum Stackoverflow und diese Methode ist daruch langsam und speicherfressend.

                        Probier es mal aus:

                          
                        function A() { A(); }  
                          
                        A();  
                        
                        

                        Wie lautet die Fehlermeldung?
                        Versuch die mal mit einem Timeout zu bekommen, es wird dir nicht gelingen.

                        Es müssen also nur lokale Variabeln zur Geltung kommen. z.b. kann so ein Array (s. Beispiel) aufgebaut werden, dass am Ende zurückgegeben wird. Das ist bei deiner Methode nicht möglich, da es keine Rekursion ist.

                        Hier mal der direkte Vergleich:

                        <form>  
                        <textarea rows=10 cols=50 name="out"></textarea>  
                        </form>  
                        <script type="text/javascript" >  
                        var o = document.forms[0].out;  
                        o.value = '';  
                        function D(txt){  
                         if(!o) return;  
                         o.value += txt + '\n';  
                        }  
                          
                        var counter = 0;  
                        function Rekursion(depth, container) {  
                         if(!container) container = [];  
                         if(!depth) return;  
                         container.push('depth:' + depth + ' call: ' + counter++);  
                          
                         Rekursion( depth - 1, container);  
                         return container  
                        }  
                        counter = 0;  
                        function keineRekursion(depth, container) {  
                         if(!container) container = [];  
                         if(!depth) return;  
                         container.push('depth:' + depth + ' call: ' + counter++);  
                          
                         window.setTimeout( function() {  
                          Rekursion( depth - 1, container);  
                         }, 1  
                         );  
                         return container  
                        }  
                        function start () {  
                        var a1 = keineRekursion(10);  
                        var a2 = Rekursion(10);  
                        D( 'keine Rekursion:\n' + a1.join('\n') )  
                        D( 'Rekursion:\n' + a2.join('\n') )  
                        }  
                        start();  
                          
                        </script>  
                        
                        

                        Die entstehenden alerts verdeutlichen übrigens die entstehende Kette...

                        Nein, nur den wiederholten aufruf und die Ausgabe einer globalen Variabel, die gibt es in der Rekursion nicht unbedingt.

                        Struppi.

  2. @@roland:

    ich möchte einen Text der in einem DIV Tag eingeschlossen ist langsam unsichtbar machen und e.v. wieder herstellen per Link.

    Suche im Archiv nach "opacity"!

    Live long and prosper,
    Gunnar

    --
    „Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann.“ (Joseph Weizenbaum)
  3. Also ich hab die Antworten jetzt mal flott durchgeblättert - muss ja nebenbei noch was tun - und wundere mich eigentlich, warum keiner Scriptaculous erwähnt...?

    Bsp.:
    prototype.js & scriptaculous.js einbinden,
    link: <a href="#" onclick="new Effekt.Fade('divxyz');return false;">blah</a>

    Hilft? Oder willste lieber das Rad neu erfinden ;DDD

    Gruß,
    Manu

    1. Ach, ich vergaß: das Gegenstück zu Fade lautet Appear...

      Gruß,
      Manu

    2. Lieber Manu,

      Hilft? Oder willste lieber das Rad neu erfinden ;DDD

      wir sind hier im SELF-Forum. "self" mag da durchaus Motto sein...

      Liebe Grüße aus Ellwangen,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
      1. Klar, wenn man für so einen Schnickschnack zig Stunden investieren will - selber machen.

        Wenn ich allerdings so eine Frage sehe, denke ich, dass eine Antwort für eine einfache (und vor allem schnelle) Möglichkeit vielleicht doch angebracht ist.

        Hast Du bei jedem Problem(chen) Zeit, das von Grunde auf neu zu lösen?
        Wenn ja: beneidenswert, wenn nein, wirst Du eine schnelle und unkomplizierte Lösung sicher vorziehen.

        Ist sicher nicht so nerdy, aber das will auch nicht jeder...
        Self einbauen/testen usw. muss er ja immer noch...

        Gruß,
        Manu

        1. Hi,

          Self einbauen/testen usw. muss er ja immer noch...

          Und wenn das, auf Grund fehlender Javascript- (HTML-/CSS-) Grundkenntnisse, nicht "funzen" sollte - dann steht er wieder hier auf der Matte.

          MfG ChrisB

        2. @@Manu:

          Hast Du bei jedem Problem(chen) Zeit, das von Grunde auf neu zu lösen?

          Nach einer fertigen Lösung zu suchen kostet auch Zeit.

          Wenn man dann schließlich doch etwas Geeignetes gefunden hat, muss man es meist an die eigenen Bedüfnisse anpassen. Dazu muss man den Quelltext wenigtens in groben Zügen verstehen. Sich in Quelltext von anderen einzulesen, kostet Zeit – mitunter sehr viel Zeit.

          Da ist man bei einem Problemchen wie diesem doch schneller, es selbst zu machen.

          Und man lernt dabei.

          Live long and prosper,
          Gunnar

          --
          „Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann.“ (Joseph Weizenbaum)