idubn: Schütteleffekt

Hallo,

ich will einen "Schütteleffekt" programmieren (so wie hier: http://wiki.script.aculo.us/scriptaculous/show/Effect.Shake, oder hier http://demo.eyeos.org/, wenn man das falsche Passwort angibt).

Mein Ansatz ist:

function shake(id, strongness, dur)
{
  document.getElementById(id).style.position = "relative";

for (var i=0; i != dur; i++)
  {
     document.getElementById(id).style.left = -1 * strongness + "px";
     document.getElementById(id).style.left = 1 * strongness + "px";
  }

document.getElementById(id).style.position = origPos;
  document.getElementById(id).style.left = origLeft;
}

Es passiert allerdings nichts Sichtbares. Ich vermute, dass die Änderungen nicht sofort sichtbar gemacht werden und ich das Endresultat (also die Ausagangsstellung) präsentiert bekomme. Wie kriege ich also die Zwischenänderungen in der Schleife zu sehen?

Vielen Dank im Voraus

Gruß, idubn

  1. Es passiert allerdings nichts Sichtbares. Ich vermute, dass die Änderungen nicht sofort sichtbar gemacht werden und ich das Endresultat (also die Ausagangsstellung) präsentiert bekomme. Wie kriege ich also die Zwischenänderungen in der Schleife zu sehen?

    Du kannst die Zeitabstände zwischen den einzelnen Durchläufen der Schleife mit setInterval() vergrößern, sodass man den Effekt besser sieht. Außerdem solltest du "1 * strongness" auf- oder abrunden, falls da mal keine Ganzzahl herauskommt.

    1. Hallo,

      Du kannst die Zeitabstände zwischen den einzelnen Durchläufen der Schleife mit setInterval() vergrößern, sodass man den Effekt besser sieht.

      Quasi so?

      function shake(id, strongness, dur)
      {
        var origPos = document.getElementById(id).style.position;
        var origLeft = document.getElementById(id).style.left;

      document.getElementById(id).style.position = "relative";

      window.setInterval("document.getElementById('" + id + "').style.left = '" + -1 * strongness + "px';document.getElementById('" + id + "').style.left = '" + 1 * strongness + "px';", 10)
        window.setTimeout("window.clearInterval();", dur * 10);
        window.setTimeout("document.getElementById('" + id + "').style.left = '" + origLeft + "';document.getElementById('" + id + "').style.position = '" + origPos + "';", (dur + 2) * 10);
      }

      Funktioniert nicht. Nur am Ende (beim clearInterval()) sieht man wie das einmal hin- und herruckelt, und dann hört der Effekt auf. :(

      Außerdem solltest du "1 * strongness" auf- oder abrunden, falls da mal keine Ganzzahl herauskommt.

      Danke für den Tip, werd ich später ändern.
       Gruß, idubn

      1. Ich hab das jetzt folgendermaßen (rekursiv) gelöst:

        function shake(obj, strongness, dur, speed, direction)  
        {  
         if (direction > 0)  
          obj.style.left = parseInt(obj.style.left) + strongness + "px";  
         else  
          obj.style.left = parseInt(obj.style.left) - strongness + "px";  
         dur -= speed / 1000;  
         if (dur <= 0)  
          return;  
         setTimeout(function(){ shake(obj, strongness, dur, speed, -1*direction); }, speed);  
        }
        

        Und wird folgendermaßen aufgerufen:

        <div onClick="shake(this, 3, 5, 1000, 1)" (...)  
        

        Wobei der erste Parameter immer "this" sein muss, der Zweite für die Stärke des Schüttelns, der Dritte für die Dauer und der Vierte für die Geschindigkeit (in Sekunde/1000) steht. Der letzte sollte einen positiven Wert haben (welcher ist egal, z.B. 1).

        1. Hallo,

          danke für deine Mühe, der Code funktioniert :)
          Ich frag mich bloß was an meinem falsch war. Nun JavaScript ist schon eine Sache für sich ;)

          Vielen Dank,
           idubn

          1. Hallo idubn,

            Ich frag mich bloß was an meinem falsch war.

            hmm,
            Du hast doch keine Aenderung gesehen, daraus folgt, dass in Deinem Script auch nix passiert, insgesamt gesehen!
            Du musst dem Browser immer Zeit einraeumen, das, was Du angewiesen hast, auch zu realisieren.
            Dazu ist z.B. eine Weiterleitung via setTimeout() bestens geeignet.

            Gruss Norbert

            1. Hallo,

              das ist mir klar.
              Aber warum hat setInterval() nicht funktioniert?

              Gruß, idubn

              --
              <meta name="selfcode" content="sh:( fo:| ch:? rl:? br:^ n4:{ ie:% mo:| va:} de:> zu:) fl:{ ss:) ls:[ js:|" />
              1. Hai idubn,

                Aber warum hat setInterval() nicht funktioniert?

                hmm,
                vielleicht weil in Deinem ersten Script sowas ueberhaupt nicht vorkommt ...

                Gruss Norbert

                1. Hallo,

                  aber in meinem zweiten Versuch schon: http://forum.de.selfhtml.org/?t=160951&m=1046956#m1046956

                  Gruß, idubn

                  --
                  <meta name="selfcode" content="sh:( fo:| ch:? rl:? br:^ n4:{ ie:% mo:| va:} de:> zu:) fl:{ ss:) ls:[ js:|" />
  2. Hallo Idubn, hallo Forum,
    da waren wieder einige Leute schneller als ich...

    Für das restliche Forumn und das Archiv: beispiel
    Wäre ja schade, wenn ich mir die Mühe für die Rundablage gemacht hätte.

    Ich weiss: so eine vorgekaute Lösung ist eigentlich nicht im Sinne von *SELF*HTML, aber ich hätte auch noch was zu setTimeout gesagt und ausserdem darauf hingewiesen, dass der Quelltext des Beispiels ruhig zu Übungszwecken geändert werden darf (ja sogar soll)

    Liebe Grüße mbr

    P.S.: Wenn mir jetzt noch einer von den wirklichen Experten das Verhalten des IE7 (IE6 konnte ich leider gerade nicht testen) beim Klicken auf die mittlere oder rechte obere Box erklären könnte...? Ich meine verstanden zu haben, dass für den IE7 '' und '0px' als Wert für style.left etwas verschiedenes sind. Aber Wieso??

    1. Hallo,

      P.S.: Wenn mir jetzt noch einer von den wirklichen Experten das Verhalten des IE7 (IE6 konnte ich leider gerade nicht testen) beim Klicken auf die mittlere oder rechte obere Box erklären könnte...? Ich meine verstanden zu haben, dass für den IE7 '' und '0px' als Wert für style.left etwas verschiedenes sind. Aber Wieso??

      Ich bin zwar kein Experte, aber bei der Parameterliste hast du oldLeft und oldPos vertauscht. Ändere '', '0px' zu '0px', '' und es klappt im IE7 ;)

      Gruß, idubn

      --
      <meta name="selfcode" content="sh:( fo:| ch:? rl:? br:^ n4:{ ie:% mo:| va:} de:> zu:) fl:{ ss:) ls:[ js:|" />
      1. Hallo Idubn

        Ich bin zwar kein Experte, aber bei der Parameterliste hast du oldLeft und oldPos vertauscht. Ändere '', '0px' zu '0px', '' und es klappt im IE7 ;)

        Danke, du hast natürlich recht. Ich denke, ich geh jetzt ins Bett (sobald ich die korrigierte Datei hochgeladen habe)

        Übrigens ein Wunder, dass der FF mit dem verkorksten Skript klarkam...

        gute Nacht

        mbr