inselfisch: Überblendung als Endlosschleife?

Hallo zusammen,

Sorry wenn ich hier was Offensichtliches übersehe, aber ich bin noch JS-Neuling. ich hab mir eine kleine Bild-Überblendungsfunktion ergooglet, die soweit sehr hübsch läuft. Das heißt, sie läuft einmal durch und bleibt dann stehen. Ist auch logisch, sie wird über einen SetTimeout geregelt. Jetzt möchte ich die selbe Funktion aber als Endlosschleife durchlaufen lassen, und produziere mit allen Versuchen nur Browserabstürze ("Skript ist beschäftigt") Hat jemand einen Tipp, wie es funktionieren könnte? Bin für jeden Hinweis dankbar.

<script>
function fadeOddballs(step) {
var imgs = document.getElementsByTagName("img");
step = step || 0;
imgs[1].style.opacity = step/100;
imgs[1].style.filter = "alpha(opacity=" + step + ")"; // IE
step = step + 2;
if (step <= 100) {
window.setTimeout(function () { fadeOddballs(step); }, 100);
}
}
</script>

Vielen Dank! inselfisch

  1. Ohne jetzt genau deine Funktion angesehen zu haben, läuft es natürlich prinzipiell so ab

    fadeOddballs() // initialer Aufruf bei e.g. Pageload
    
    function fadeOddballs(){
    
      // was auch immer...
    
      window.setTimeout(fadeOddballs, 100); // verzögerter Selbstaufruf
    
    }
    

    Hier hab ich mal die Kurzschreibweise gewählt, sofern du den step parameter nicht dringend brauchst... Und das Interval auf jeden Fall hochsetzen! Alle 5 sek würde 5000 sein.

    EDIT: jetzt, wo ich doch mal deine Funktion angesehen habe und sehe, dass Du es im Prinzip genau so gemacht hast, fällt mir auf, dass es wohl ein Scopeproblem ist. Schreib mal

    var step; 
    

    außerhalb der Funktionsdeklaration von fadeOddballs(), dass macht es zu einer globalen Variable.

    Cheers,
    BaBa

    --
    BaBa kommt von Basketball
    1. Danke BaBa, ich probiers mal!

      [Vollzitat entfernt]

      1. Danke BaBa, ich probiers mal!

        Danke für's Danke, aber die Kritik an den globalen Variablen ist bestimmt berechtigt... war mir nicht klar. Ich glaube aber, dass die Lösung funktioniert. Aber auch den Performanceaspekt würde ich berücksichtigen. Das hatte ich mir gar nicht angesehen.

        Viel Erfolg

        Cheers,
        BaBa

        --
        BaBa kommt von Basketball
        1. Hej BaBa,

          Danke BaBa, ich probiers mal!

          Danke für's Danke, aber die Kritik an den globalen Variablen ist bestimmt berechtigt...

          Trotzdem nett, dass du zu helfen bereit bist. Du bist ja nicht der einzige hier und die Sache konnte noch geklärt werden. Grundsätzlich gilt:

          1. Inhalte (gerne auch dynamisch) ins Dokument (HTML)! Zum Beispiel Bilder, die erläuternd wirken.

          2. Für die Präsentation (z. B. aufhübschende Bilder, ohne inhaltliche Relevanz oder Rahmen um inhaltlich relevante Bilder, aber auch um die Bilder zu animieren): CSS

          3. Funktionalität (z. B. Bild gegen ein anderes austauschen aufgrund von Nutzereingaben) clientseitig mit JS, serverseitig mit der (oft vorgegebenen) bereitstehenden Sprache (Java, PHP, whatever...)

          Übrigens: die Berechnung von Animationen durch JavaScript ist aufwändiger (und damit prozessor-, batterie- und wärmetechnisch kritischer) als CSS-Animationen, die vom Browser berechnet werden. Daher laufen CSS-Animationen idR auch flüssiger.

          Das aber nur am Rande. Die Trennung von Inhalt, Präsentation und Funktion ist ein konzeptioneller Vorteil, der allein schon die "korrekte" Verwendung der Sprachen HTML, CSS und JS rechtfertigt.

          Marc

  2. benutz doch lieber setInterval()

  3. Vorbemerkung 1: alpha(opacity=n) ist uralt, das kansnt Du weglassen. Ab IE9 reicht opacity.

    Vorbemerkung 2: Mache step NICHT zu einer globalen Variable. Man soll in JavaScript auf Globals wann immer möglich verzichten. Eine lokale Variable ist für deine Aufgabe. Eine globale Variable brauchst Du nur dann, wenn Du einen Mechanismus benötigst, um die Animation von außerhalb zu stoppen. WENN Du globale Variablen brauchst, dann solltest Du EIN globales Objekt erzeugen, z.B. "InselFisch = {};", und in diesem Objekt alles eintüten was Du an Globalitäten brauchst. Damit hast Du einen eindeutigen Container, der nur Dir gehört und Du läufst nicht Gefahr, dass globale Daten zweier Scripte miteinander kollidieren.

    Vorbemerkung 3: Identifiziere Dein Image nicht per document.getElementsByTagName("img"). Der Zugriff auf das Element [1] des resultierenden Arrays ist eine magische Zahl und fehleranfällig. Gib dem Image eine ID und benutze getElementById(). Oder gib allen Images, deren Transparenz pulsieren soll, eine Klasse, benutze getElementsByClassName und laufe über alle Elemente des resultierenden Arrays.

    So. Nun zu deinem Wunsch :)

    setTimeout() "hinterlegt" sozusagen einen Funktionsaufruf, der nach Ablauf der genannten Zeit automatisch vom Brauser aufgerufen wird. Der Wert von step aus dem n-ten Aufruf wird dabei mit gespeichert und dem (n+1)-ten Aufruf übergeben. Die Fassung, die Du gepostet hast, ruft für step>100 keinen setTimeout mehr auf und beendet damit die Animation.

    Um eine Endlosschleife zu erzeugen, empfehle ich Dir

    step = step % 100 + 2;
    window.setTimeout(function () { fadeOddballs(step); }, 100);
    

    D.h. kein IF mehr und dafür beim Erhöhen von step durch Modulo 100 dafür sorgen, dass die Variable die Folge 2, 4, ..., 96, 98, 100, 2, 4, ... , 96, 98, 100, 2, 4, ... , durchläuft.

    Wenn Du die Opacity auf- und ablaufen lassen möchtest, brauchst Du einen zweiten Parameter der die aktuelle Laufrichtung angibt und musst die Änderung von step entsprechend anpassen. Das überlasse ich Dir als Übung :D

    Gruß Rolf

  4. @@inselfisch

    Sorry wenn ich hier was Offensichtliches übersehe, aber ich bin noch JS-Neuling. ich hab mir eine kleine Bild-Überblendungsfunktion ergooglet, die soweit sehr hübsch läuft.

    Ein Blick in den Code sagt mir anderes.

    function fadeOddballs(step) {
    var imgs = document.getElementsByTagName("img");
    

    Autsch! In einer Funktion, die du 10 Mal pro Sekunde aufrufst, durchsuchst du jedes Mal erneut das gesamte DOM nach allen img-Elementen. Nicht machen, auf gar keinen Fall. Das Raussuchen des Bildes aus dem DOM solltest du nur einmal machen – vor dem ersten Aufruf der Funktion.

    Aber eigentlich solltest du das gar nicht machen. Ich kann nichts erkennen, was hier überhaupt eine Zeile JavaScript rechtfertigen würde. Dein Vorhaben sollte mit CSS-Animationen umsetzbar sein.

    Jetzt möchte ich die selbe Funktion aber als Endlosschleife durchlaufen lassen

    ?? Was genau soll denn passieren, nachdem das Bild völlig opak geworden ist?

    LLAP 🖖

    --
    “You might believe there are benefits for the developer, but first of all, you should put those behind the interest of the user.” —Stefan Tilkov
    Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
    1. Autsch! In einer Funktion, die du 10 Mal pro Sekunde aufrufst, durchsuchst du jedes Mal erneut das gesamte DOM nach allen img-Elementen. Nicht machen, auf gar keinen Fall. Das Raussuchen des Bildes aus dem DOM solltest du nur einmal machen – vor dem ersten Aufruf der Funktion.

      Ist einerseits was dran - aber was ist andererseits, wenn sich das DOM ändert? Aus meiner Sicht ist das Cachen von DOM Referenzen über Script-Zyklen hinweg riskant. Deshalb mein Vorschlag mit ID oder CLASS; an den Performance-Aspekt bei fetten Seiten hatte ich gar nicht gedacht...

      Was mit neuerem CSS alles so geht, wäre sicherlich auch zu eruieren, aber davon habe ich (a) selbst keine Ahnung und (b) weiß man ja auch nicht, welches Lernziel der Inselfisch (oder die Fischerin?) hat.

      Gruß Rolf

      1. @@Rolf b

        aber was ist andererseits, wenn sich das DOM ändert? Aus meiner Sicht ist das Cachen von DOM Referenzen über Script-Zyklen hinweg riskant.

        Nichts ist dann. Die einmal rausgesuchte Refenz auf das Elementobjekt bleibt bestehen, auch wenn sich das DOM ändert. Kuckst du.

        Was mit neuerem CSS alles so geht

        Geht. [EDIT: Link berichtigt.]

        und (b) weiß man ja auch nicht, welches Lernziel der Inselfisch (oder die Fischerin?) hat.

        Das Lernziel kann sein: „Mache eine Überblendung auf einer Webseite. Wähle die dafür sinnvolle Technologie.“

        Das Lernziel sollte nicht sein: „Mache eine Überblendung auf einer Webseite. Mache das mit JavaScript.“

        Letzteres ist blanker Unsinn.

        LLAP 🖖

        --
        “You might believe there are benefits for the developer, but first of all, you should put those behind the interest of the user.” —Stefan Tilkov
        Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
        1. Hi all ihr freundlichen Antworter,

          Mit dem Lernziel "Mache eine Überblendung auf einer Webseite. Wähle die dafür sinnvolle Technologie" bin ich einverstanden :)

          Ich guck mir das jetzt alles mal in Ruhe an, melde mich wieder wenn ich durch die vielen Tipps durchgestiegen bin. Danke euch allen!

          Die inselfischin

          1. @@inselfisch

            Mit dem Lernziel "Mache eine Überblendung auf einer Webseite. Wähle die dafür sinnvolle Technologie" bin ich einverstanden :)

            Ich guck mir das jetzt alles mal in Ruhe an

            Jetzt kann du kucken. Ich hatte einen falschen Codepen verlinkt. Hier der sinnvolle.

            LLAP 🖖

            --
            “You might believe there are benefits for the developer, but first of all, you should put those behind the interest of the user.” —Stefan Tilkov
            Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
            1. Hab geguckt - WOW! Da kann ich jetzt echt was lernen, vielen, vielen Dank!

              Liebe Grüße vom inselfisch <------geht jetzt mal das jscript einstampfen ;)

              Jetzt kann du kucken. Ich hatte einen falschen Codepen verlinkt. Hier der sinnvolle.

            2. Hallo Gunnar,

              noch eine kleine Fußnote: Deine Lösung schlägt mehrere Fliegen mit einer Klappe :) Wenn ich auf derselben Seite ein zweites Div mit zwei Bildern einbaue (haben zufällig die gleiche Größe wie die ersten), werden die auch hübsch überblendet - eigentlich logisch, du setzt ja die Eigenschaften komplett für div und img, das zieht für alle.

              Jetzt schau ich mir mal an, wie das mit abgeleiteten Klassen funktionieren könnte... menno, steile Lernkurve für einen Anfänger, danke nochmal!

              Beste Grüße vom inselfisch

            3. @@Gunnar Bittersmann

              Jetzt kann du kucken. Ich hatte einen falschen Codepen verlinkt. Hier der sinnvolle.

              Danke für die Anregung!

              Konnte ich gut für mein aktuelles Projekt gebrauchen :)

        2. aber was ist andererseits, wenn sich das DOM ändert?

          Nichts ist dann. Die einmal rausgesuchte Refenz auf das Elementobjekt bleibt bestehen, auch wenn sich das DOM ändert. Kuckst du.

          Sorry, habe mich unklar ausgedrückt. Ich dachte an die Leaks, die man bekommt, wenn man eine Referenz auf ein DOM Objekt hält das per Script gelöscht wird. Bei 20 Zeilen Script geht das noch. Aber wenn man sich sowas angewöhnt und dann im größeren Stil loslegt...

          Rolf

        3. @@Gunnar Bittersmann

          Geht.

          Da gehst du zum Italiener, schlägst die Speisekarte auf und denkst: die Bilder kennste doch‽

          Speisekarte mit denselben beiden Bildern wie im Codepen

          LLAP 🖖

          --
          “You might believe there are benefits for the developer, but first of all, you should put those behind the interest of the user.” —Stefan Tilkov
          Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
    2. Das ist eine sehr berechtigte Frage, danke! Ich denke, es soll wieder rückwärts in der Opacity reduziert werden, bis wieder das erste Bild sichtbar ist. Mhm, das hätte ich mir vorher überlegen sollen.... ich geh mal mein Denkmützerl aufsetzen.

      ?? Was genau soll denn passieren, nachdem das Bild völlig opak geworden ist?

      LLAP 🖖

      1. Math.sin(x) ? :D

    3. Ich kann nichts erkennen, was hier überhaupt eine Zeile JavaScript rechtfertigen würde. Dein Vorhaben sollte mit CSS-Animationen umsetzbar sein.

      Was Du mittels des Code-Pen ja auch soweit untermauert hast. Funktioniert ohne JavaScript und ist obendrein auch vermutlich performanter! Ich persönlich konnte und kann mit der Verwendung des Konzepts von Keyframes aber wenig anfangen. Das habe ich zu Zeiten von Flash schon gehasst und die Variante mittels ActionScript bevorzugt. Auch heute scheint mir die Variante z.B. mittels jQuery "fadeTo" einfach deutlich intuitiver und lesbarer. Geht das nur mir so?

      1. Hej Mitleser,

        Ich persönlich konnte und kann mit der Verwendung des Konzepts von Keyframes aber wenig anfangen. Geht das nur mir so?

        Keine Ahnung, aber neben vielen anderen tollen Ideen und Erklärungen, widmet sich Lea Verou in merheren ihrer CSS-Geheimnissen auch Animationen. Auch den keyframes - sie hat eine überzeugende Art, schwer zu merkende Dinge anschaulich und verständlich zu visualisieren. Daher eine Lesempfehlung, auch wenn es weit über das hier angesprochene Thema hinaus geht:

        CSS Secrets

        Toll auch als Kindle mit Möglichkeiten zu Anmerkungen usw...

        Das Buch selber ist übrigens als HTML/CSS-Konstrukt entstanden.

        Marc

      2. @@Mitleser

        Ich persönlich konnte und kann mit der Verwendung des Konzepts von Keyframes aber wenig anfangen. Das habe ich zu Zeiten von Flash schon gehasst und die Variante mittels ActionScript bevorzugt. Auch heute scheint mir die Variante z.B. mittels jQuery "fadeTo" einfach deutlich intuitiver und lesbarer. Geht das nur mir so?

        Ich finde eine deklarative Sprache – wie es CSS eine ist – hierfür deutlich einfacher. Du beschreibst einfach nur: zum Zeitpunkt 0 soll es so aussehen, zum Zweitpunkt _t_₁ so, zum Zweitpunkt _t_₂ so … und am Ende so. Die Zwischenschritte soll der Browser bitteschön selbst berechnen.

        In einer imperativen Sprache wie JavaScript hingegen berechnest du jeden einzelnen Zwischenschritt. (Teile die Veränderung von Anfang bis Ende durch n; Schleife über n Schritte: Verändere den Wert um eine Winzigkeit.)

        Mit einer Bibliothek wie jQuery machst du auch nichts anderes als die Zwischenschritte wegzukapseln und Keyframes anzugeben. (fadeIn() ist allerdings eher mit CSS-Transition zu vergleichen als mit CSS-Animation.)

        LLAP 🖖

        --
        “You might believe there are benefits for the developer, but first of all, you should put those behind the interest of the user.” —Stefan Tilkov
        Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
        1. Hallo Gunnar Bittersmann,

          Ich finde eine deklarative Sprache – wie es CSS eine ist –

          deklarative Sprache - ja, deklararative Programmierung - nein. Auch Präprozessoren sind mMn. keine Programmiersprachen. Aber dieser Streit ist wohl so alt, wie CSS selbst.

          Mit einer Bibliothek wie jQuery machst du auch nichts anderes als die Zwischenschritte wegzukapseln und Keyframes anzugeben.

          replace('auch','- genau wie in CSS - auch')

          Bis demnächst
          Matthias

          --
          Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
          1. @@Matthias Apsel

            Ich finde eine deklarative Sprache – wie es CSS eine ist –

            deklarative Sprache - ja, deklararative Programmierung - nein.

            Natürlich nicht. Wollte ich auch nicht gesagt haben. https://de.wikipedia.org/wiki/Deklarative_Sprache leitet zu Deklarative Programmierung weiter, da hatte ich gleich letzteres verlinkt.

            Auch Präprozessoren sind mMn. keine Programmiersprachen.

            CSS-Präprozessoren würde ich mit Templatesprachen in einen Topf werfen.

            Hm, ist XSLT keine Programmiersprache?

            Aber dieser Streit ist wohl so alt, wie CSS selbst.

            Das Komma da kannst du an jemanden abtreten der zuwenig davon verwendet.

            LLAP 🖖

            --
            “You might believe there are benefits for the developer, but first of all, you should put those behind the interest of the user.” —Stefan Tilkov
            Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
            1. Huiiii, was hab ich da nur für einen Disput losgetreten... hochinteressant! Ich danke allen Beteiligten für die Hilfe und die anregende Diskussion und geh jetzt mein CSS umbauen.

              LG vom inselfisch

            2. Hallo Gunnar Bittersmann,

              Aber dieser Streit ist wohl so alt, wie CSS selbst.

              Das Komma da kannst du an jemanden abtreten der zuwenig davon verwendet.

              Geb ich dir gern.

              Bis demnächst
              Matthias

              --
              Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
              1. Hallo,

                Das Komma da kannst du an jemanden abtreten der zuwenig davon verwendet.

                Geb ich dir gern.

                wird wohl nicht reichen...

                Gruß
                Kalk