Malte: Endlosschleife verhindern

Hallo,

ich habe zwei einfache Javascripte geschrieben/umgeändert, um <div>-Container zu bewegen, konkret Navigationsmenüs ein- und auszusliden. slideDown() fährt das Menü aus, slideUp() fährt es wieder ein.

Problem: Wenn slideUp() aufgerufen wird, bevor slideDown() beendet wurde, kollidieren die beiden Scripte, keines kann je sein Ende erreichen, die CPU fährt auf 100% und der <div>-Container bleibt zitternd hängen.

Mir ist schon klar, warum das so ist (liegt an meinen Abbruchbedingungen), aber ich weiß nicht so recht, wie ich das verhindern kann. Bei einem Abbruch vor Beendigung soll der betr. Container im Zweifelsfall "hochfahren".

Ich hab es schon mit einer for-Schleife in slideDown() probiert, so daß diese Funktion maximal $TARGET-mal durchlaufen wird, das funktioniert aber gar nicht - es passiert dann schlicht nichts.

Any hints?

Gruß,

Malte.

function slideDown(whichone,target){
  if(document.getElementById){
    if(parseInt(document.getElementById(whichone).style.top) < target){
      document.getElementById(whichone).style.top = parseInt(document.getElementById(whichone).style.top) + 1 + "px";
      myDown = "slideDown('" + whichone + "'," + target + ")";
      setTimeout(myDown,1);
    }
  }
}

function slideUp(whichone,target){
  if(document.getElementById){
    if(parseInt(document.getElementById(whichone).style.top) > target){
      document.getElementById(whichone).style.top = parseInt(document.getElementById(whichone).style.top) - 1 + "px";
      myUp = "slideUp('" + whichone + "'," + target + ")";
      setTimeout(myUp,1);
    }
  }
}

  1. Hallo,

    so auf die schnelle fällt mir dazu ein...

    wie wäre es wenn du einen "flag" für sliding up einführst?

    var slidingUp = false;

    function slideDown(whichone,target){
      if(document.getElementById){
        if(parseInt(!slidingUp && document.getElementById(whichone).style.top) < target){
          document.getElementById(whichone).style.top = parseInt(document.getElementById(whichone).style.top) + 1 + "px";
          myDown = "slideDown('" + whichone + "'," + target + ")";
          setTimeout(myDown,1);
        }
      }
    }

    function slideUp(whichone,target){
      if(document.getElementById){
        if(parseInt(document.getElementById(whichone).style.top) > target){
          document.getElementById(whichone).style.top = parseInt(document.getElementById(whichone).style.top) - 1 + "px";
          myUp = "slideUp('" + whichone + "'," + target + ")";
    slidingUp = true;
    setTimeout(myUp,1);
        }
        else
        {
           slidingUp = false;
        }
      }
    }

    Gruß,
    Cruz

    1. Hi,

      wie wäre es wenn du einen "flag" für sliding up einführst?

      Danke! Das war der richtige Wink. Nachdem ich die Abfrage an die richtige Stelle des if-Statements gepackt hatte und das flag nicht boolean'sch, sondern string'sch angewandt habe, funktioniert es. Es muß deshalb den Namen des aktiven Elementes tragen, weil ich diese Funktionen auf verschiedene Elemente anwende, und das teilweise zeitgleich. Nochmals Danke.

      Gruß,

      Malte.

      var slidingUp = "";

      function slideDown(whichone,target){
        if(document.getElementById){
          if(slidingUp != whichone && parseInt(document.getElementById(whichone).style.top) < target){
            document.getElementById(whichone).style.top = parseInt(document.getElementById(whichone).style.top) + 1 + "px";
            myDown = "slideDown('" + whichone + "'," + target + ")";
            setTimeout(myDown,1);
          }
        }
      }

      function slideUp(whichone,target){
        if(document.getElementById){
          if(parseInt(document.getElementById(whichone).style.top) > target){
            document.getElementById(whichone).style.top = parseInt(document.getElementById(whichone).style.top) - 1 + "px";
            myUp = "slideUp('" + whichone + "'," + target + ")";
            slidingUp = whichone;
            setTimeout(myUp,1);
          }
          else
          {
             slidingUp = "";
          }
        }
      }

  2. Problem: Wenn slideUp() aufgerufen wird, bevor slideDown() beendet wurde, kollidieren die beiden Scripte, keines kann je sein Ende erreichen, die CPU fährt auf 100% und der <div>-Container bleibt zitternd hängen.

    Dann muss der Prozess slieDown beendet werden. Einen Tipp hast du ja schon bekommen

    Ich hab es schon mit einer for-Schleife in slideDown() probiert, so daß diese Funktion maximal $TARGET-mal durchlaufen wird, das funktioniert aber gar nicht - es passiert dann schlicht nichts.

    Dann hast du die Schleife falsch programmiert.

    Any hints?

    Ja.

    function slideDown(whichone,target){
      if(document.getElementById){
        if(parseInt(document.getElementById(whichone).style.top) < target){
          document.getElementById(whichone).style.top = parseInt(document.getElementById(whichone).style.top) + 1 + "px";
          myDown = "slideDown('" + whichone + "'," + target + ")";
          setTimeout(myDown,1);
        }
      }
    }

    Einen timeout mit einer Millisekunde?
    Da ist eine Schleife wiklich sinnvoller, da die Funktion mit Sicherheit nicht in einer millisekunde ausgeführt werden kann, zumal getElement.... relativ Zeitintensive Funktionen sind. du solltest vermeiden diese mehrmals aufzurufen.

    function slideDown(whichone,target){
    if(!document.getElementById) return
    var obj = document.getElementById(whichone);
    for(var i = parseInt(obj.style.top); i < target; i++)
     obj.style.top = i + "px";
    }

    (ungetestet)

    Struppi.