Roadster: Universelle Event-Listener-Zielfunktion(en)?

Hallo miteinander!

Ein Beitrag von Camping_RIDER...

https://forum.selfhtml.org/?t=219016&m=1510954

...und ein Beitrag von JürgenB...

https://forum.selfhtml.org/?t=219016&m=1511130

...haben mich zu einer grundsätzlichen Frage hingeführt, und zwar:

Warum ist es überhaupt nötig oder ratsam, Event-Listener an bestimmte Elemente zu knüpfen?

Bislang bin ich immer nach folgendem Schema vorgegangen...

function addEventListenerForElement() {  
  
    document.getElementById("element").addEventListener("click", elementOnClick);  
  
}

...aber eingedenk der (für mich neuen) Tatsache, dass man ja auch in der Event-Listener-Zielfunktion über einen Parameter (e) das auslösende Element bestimmen kann...

function elementOnClick( e ) {  
  
    var element = e.target.id;  
  
    doSomethingWith(element);  
  
}

...OHNE den Event-Listener zuvor auch an 'dieses' Element angeknüpft zu haben, frage ich mich, wozu dann überhaupt noch individuelle "addEventListener"-Funktionen verwenden?

Ich meine, man könnte ja auch einfach für jedes Event, "click", "mouseover", "mouseout", "animationstart", "animationiteration", "animationend" usw. usw. einfach jeweils genau einen Event-Listener hinzufügen...

function addEventListenerForClick() {  
  
    var body = document.getElementsByTagName("BODY")[0];  
  
    body.addEventListener("click", onClickFunction);  
  
}

...und dann einfach nur in der Zielfunktion entscheiden, was dann weiter passieren soll!

Wozu also überhaupt den Aufwand betreiben individuelle Event-Listener zu installieren?

Das wars für 2014! ;)

Frohes Neues!

Gruß,

Roadster.

  1. Hallo miteinander!

    Also ich habe mir nochmal ein paar Gedanken dazu gemacht und bin zu dem vorläufigen Ergebnis gekommen, dass die 'klassische' Methode, jedem Element seinen spezifischen Event-Listener und seine spezifische Zielfunktion anzuhängen, doch in der Praxis eher in Ausnahmefällen sinnvoll ist, wohingegen Event-Delegation wohl in der Mehrheit der Fälle das Mittel der Wahl sein sollte, denn element.addEventListener("event", elementOnEvent); macht ja eigentlich nur Sinn, wenn es sich tatsächlich um ein in seinen Eigenschaften einzigartiges Element handelt, welches auch auf einzigartige Art und Weise auf ein Event reagieren soll, was in der Praxis ja eher die Ausnahme sein dürfte...

    Daher noch als Anmerkung zu http://wiki.selfhtml.org/wiki/JavaScript/Objekte/DOM/event/addEventListener :
    Nicht, dass das alles nicht in der Doku nachzulesen wäre, aber ich fände es sinnvoll, wenn die Informationen zur Event-Delegation nicht so gut versteckt auf Seite drei eines Links zu suchen wären, sondern direkt unter dem Artikel für die 'addEventListener'-Funktion zumindest angerissen würden, eingedenk der Wichtigkeit für die praktische Arbeit damit, - oder wenn alternativ in Form eines Kurzartikels in 'JS: Anwendung und Praxis' darauf eingegangen würde.

    Hätte mir viel Geschreibsel erspart, wenn ich bei der Recherche direkt mit der Nase darauf gestoßen worden wäre. ;)

    Soweit,

    Gruß und frohes Neues,

    Roadster.

    1. Aloha ;)

      Also ich habe mir nochmal ein paar Gedanken dazu gemacht und bin zu dem vorläufigen Ergebnis gekommen, dass die 'klassische' Methode, jedem Element seinen spezifischen Event-Listener und seine spezifische Zielfunktion anzuhängen, doch in der Praxis eher in Ausnahmefällen sinnvoll ist, wohingegen Event-Delegation wohl in der Mehrheit der Fälle das Mittel der Wahl sein sollte, denn element.addEventListener("event", elementOnEvent); macht ja eigentlich nur Sinn, wenn es sich tatsächlich um ein in seinen Eigenschaften einzigartiges Element handelt, welches auch auf einzigartige Art und Weise auf ein Event reagieren soll, was in der Praxis ja eher die Ausnahme sein dürfte...

      Jein. Tatsächlich ist es eine Abwägungsfrage. Ich möchte vor allem das folgende zu bedenken geben: Stell dir vor, du hast ein Container-div. Diesem hängst du ein Klickevent an. Das div-Element bekommt dynamisch Kind-Elemente dazu. Der Vorteil liegt nun auf der Hand: Du musst nicht jedem Kind-Element einzeln einen individuellen Event-Listener mitgeben. Und noch besser (falls das gewünscht ist): Sobald du ein Kindelement aus dem Container nimmst und woanders ablegst, reagiert es nicht mehr auf Klicks.

      Simples Beispiel: Ein Schachbrett. Die Figuren klickbare img-Elemente innerhalb divs (die Felder) innerhalb eines großen divs (das Schachbrett). Das Schachbrett hört auf onclick. Solange die Figuren auf dem Schachbrett sind, sollen sie anklickbar sein. Sobald sie geschlagen werden, werden sie dynamisch in ein Ablagestapel-div außerhalb des Schachbrett-divs gelegt und sind damit automatisch nicht mehr anklickbar. Ein Bauer, der verwandelt wird, kann auf den Ablagestapel gelegt werden und für ihn kann eine Digur vom Ablagestapel aufs Schachfeld gestellt werden. Kein lästiges hinzufügen und entfernen von Event-Handlern.

      Anderes Beispiel: je nach Container sollen die Elemente unterschiedliche klick-Aktionen ausführen, die Elemente können jederzeit in einen anderen Container hüpfen.

      In anderen Anwendungen ist genau dieses Verhalten das, was man NICHT will. Wie gesagt: es ist eine auf die konkrete Anwendung bezogene Abwägung, was im konkreten Fall geschickter und eleganter ist.

      Daher noch als Anmerkung zu http://wiki.selfhtml.org/wiki/JavaScript/Objekte/DOM/event/addEventListener :
      Nicht, dass das alles nicht in der Doku nachzulesen wäre, aber ich fände es sinnvoll, wenn die Informationen zur Event-Delegation nicht so gut versteckt auf Seite drei eines Links zu suchen wären, sondern direkt unter dem Artikel für die 'addEventListener'-Funktion zumindest angerissen würden, eingedenk der Wichtigkeit für die praktische Arbeit damit, - oder wenn alternativ in Form eines Kurzartikels in 'JS: Anwendung und Praxis' darauf eingegangen würde.

      Dann: Im wiki anmelden und dazuschreiben ;) jeder kann, darf und soll nach bestem wissen und gewissen etwas beitragen ;)

      Auch von mir an dich und alle Mitleser ein "frohes Neues" ;)

      Grüße,

      RIDER

      --
      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
      ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
      1. Aloha ;)

        Hallo RIDER :)

        Jein. Tatsächlich ist es eine Abwägungsfrage [...] In anderen Anwendungen ist genau dieses Verhalten das, was man NICHT will. Wie gesagt: es ist eine auf die konkrete Anwendung bezogene Abwägung, was im konkreten Fall geschickter und eleganter ist.

        Das ist alles unbestritten! ;) Nach meinen (zugegeben begrenzten) Erfahrungen ist es aber doch so, dass Event-Delegation bzw. die 'Nutzbarmachung' von Event-Bubbling, wohl rein _quantitativ_ betrachtet in der geübten Praxis in deutlich mehr Fällen die Methode der Wahl sein dürfte, als die, nennen wir sie: Standardprozedur.

        Wenn ich mein eigenes Programm mal unter diesem Aspekt durchleuchte, würde ich wohl zu dem Ergebnis kommen, dass es insgesamt wohl nur 1 oder 2 Fälle gibt, wo Event-Delegation weniger effizient wäre als die 'Standardprozedur', - was auf's Ganze bezogen bedeutet, dass in grob überschlagen 95% aller Anwendungsfälle in meinem Programm Event-Delegation vorzuziehen (gewesen) wäre! - Ehrlich, du glaubst nicht, wieviele Zeilen Code ich einsparen würde (und werde), wenn ich dieses Prinzip konsequent anwende(n würde)! :D

        Ganz davon abgesehen, dass sich dadurch die ganze Programmstruktur deutlich eleganter gestaltet, in dem Sinne, dass Funktionalität an wenigen Stellen zusammengeführt wird, statt sie über viele Funktionen zu verteilen, sprich, dass man dadurch im Code gewisse Knotenpunkte (nicht zu verwechseln mit DOM-Nodes ;) - bzw. 'Verteilerfunktionen' erhält, über die sich die Funktionalitäten zentral steuern lassen, was in Punkto Übersichtlichkeit einen unschätzbaren Vorteil darstellt!

        Und das ist der eigentliche Punkt (der mir im Eingangspost leider noch nicht so klar vor Augen war): Wenn etwas für die Praxis so bedeutsam ist, sollte diese Information nicht irgendwo auf den hinteren Seiten versteckt werden, denn wer als Anfänger den besagten Artikel über die 'addEventListener'-Methode liest, wird sich mit der 'Standardprozedur' zufrieden geben und diese im Zweifel hunderte Male anwenden, bevor er überhaupt mitbekommt, dass es dazu Alternativen gibt.

        Insofern halte ich es eben für extrem wichtig, dass an entsprechender Stelle zumindest erwähnt wird, dass es noch andere Optionen gibt, so dass ich als Leser eine Motivation habe, mich eingängiger mit der Materie zu befassen. - Oder, anders formuliert - und das betrifft ja nicht nur selfHTML - denke ich, dass in allen Lehrartikeln die Materie halt genau andersherum aufbereitet und dargestellt werden sollte, sprich, die Informatinonen zu Event-Bubbling bzw. die Anwendungsbeispiele zu Event-Delegation als Standardvariante, die Einzel-Element-bezogene Prozedur als Ausnahme für Fälle in denen das sinnvoll ist. - Das mag zwar rein empirisch betrachtet unsauber erscheinen, aus didaktischer Sicht heraus denke ich aber, dass das der bessere Weg wäre.

        Dann: Im wiki anmelden und dazuschreiben ;) jeder kann, darf und soll nach bestem wissen und gewissen etwas beitragen ;)

        Ach RIDER! ;) Ich bin doch nur ein bescheidener Anfänger! :D So gewichtige Aufgaben traue ich mir nicht zu! Naja, mal sehen, wenn ich Zeit habe. ;)

        Auch von mir an dich und alle Mitleser ein "frohes Neues" ;)

        Dir auch!

        Gruß,

        Roadster.

        1. Aloha ;)

          Ach RIDER! ;) Ich bin doch nur ein bescheidener Anfänger! :D So gewichtige Aufgaben traue ich mir nicht zu! Naja, mal sehen, wenn ich Zeit habe. ;)

          Ach Roadster, wenn ich mir deine Entwicklung hier imForum in den letzten Monaten anseh, dann bin ich mir ziemlich sicher, dass die Bezeichnung Anfänger nicht mehr unbedingt passend ist ;)

          Ich bezeichne mich ja gern als interessierten Laien, vielleicht passt das bei dir auch besser ;)

          Grüße,

          RIDER

          --
          Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
          ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
          1. Aloha ;)

            Hallo RIDER :)

            Ach Roadster, wenn ich mir deine Entwicklung hier im Forum in den letzten Monaten anseh, dann bin ich mir ziemlich sicher, dass die Bezeichnung Anfänger nicht mehr unbedingt passend ist ;)

            Naja, es stimmt schon, ich habe in der Zeit eine Menge gelernt, aber dabei leider auch meine eigentlichen studentischen Pflichten unentschuldbar vernachlässigt, was sich noch bitter rächen könnte...

            Ich bezeichne mich ja gern als interessierten Laien, vielleicht passt das bei dir auch besser ;)

            Mich auf eine Stufe mit dir zu stellen, wäre definitiv zuviel der Ehre! :D

            Ist "fortgeschrittener Anfänger" eine Kontradiktion? - Falls das durchgeht, würde ich mich fortan lieber so bezeichnen... ;)

            Gruß,

            Roadster.

            1. Aloha ;)

              Ach Roadster, wenn ich mir deine Entwicklung hier im Forum in den letzten Monaten anseh, dann bin ich mir ziemlich sicher, dass die Bezeichnung Anfänger nicht mehr unbedingt passend ist ;)

              Naja, es stimmt schon, ich habe in der Zeit eine Menge gelernt, aber dabei leider auch meine eigentlichen studentischen Pflichten unentschuldbar vernachlässigt, was sich noch bitter rächen könnte...

              Du sprichst mir ja sowas von aus der Seele :D Und nachdem Weihnachten jetzt vorbei ist rückt der Prüfungszeitraum wieder näher :\

              Ist "fortgeschrittener Anfänger" eine Kontradiktion? - Falls das durchgeht, würde ich mich fortan lieber so bezeichnen... ;)

              Das geht in Ordnung, junger Padawan :D

              Grüße,

              RIDER

              --
              Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
              ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
              1. Hallo :)

                Du sprichst mir ja sowas von aus der Seele :D Und nachdem Weihnachten jetzt vorbei ist rückt der Prüfungszeitraum wieder näher :\

                Auf den Punkt gebracht! Noch weniger als sechs Wochen bis zu der 5-Stunden-Klausur, die darüber entscheided, ob ich ein ganzes Jahr (und einen Großteil meiner Selbstachtung) verliere, oder endlich etwas Licht am Ende des Tunnels erblicken darf...

                Werde möglicherweise für diese Zeit meinen Computer abstöpseln, in eine Kiste packen und selbige irgendwo unzugänglich im Keller verstecken, um mich dazu zu zwingen, mich mit Arbeitsrecht statt mit JavaScript zu beschäftigen! - Also für den Fall, dass meine Abwesenheit auffällt: Bitte nicht gleich von meinem Ableben ausgehen! - I'll be back! ;)

                Gruß,

                Roadster.

  2. Hallo miteinander!

    Ich übe mich mal wieder in der Praxis, in Freibeutermanier meinen eigenen Thread zu kapern, um noch ein paar Fragen loszuwerden, deren grundsätzliche Sinnhaftigkeit gerne angezweifelt werden darf, die aber für mich in meiner konkreten Situation durchaus von Interesse sind. ;)

    Thema: Animieren mit JavaScript! :D

    Ich habe im Prinzip drei Arten von CSS-Animationen, die ich gerne in JavaScript simulieren möchte:

    Einmal eine klassische Ladebalken-Animation...

    function progressing() {  
      
      var progress = document.getElementById("progress");  
      
      var width = parseInt(progress.style.width);  
      
      progress.style.width = width + 4 + "px";  
      
      if(width < 276) {  
      
        setTimeout(progressing, 10);  
      
      }  
      
    }
    

    ...sowie eine Fade-In-Animation...

    function fadeIn(element,step) {  
      
      var step = step || 0;  
      
      element.style.opacity = step/100;  
      
      var step = step + 1;  
      
      if(step <= 100) {  
      
        setTimeout(function() {  
      
          fadeIn(element,step);  
      
        }, 15);  
      
      }  
      
    }
    

    ...und eine Rotation-Animation, für die ich in JS noch keine Umsetzung versucht habe...

    .rotate {  
      
      animation-name: rotation;  
      animation-duration: 0.5s;  
      animation-iteration-count: infinite;  
      animation-direction: alternate;  
      animation-play-state: paused;  
      animation-timing-function: ease-in-out;  
      
    }  
    @keyframes rotation {  
      
       0% {transform: rotateX(0deg);}  
     100% {transform: rotateX(90deg);}  
      
    }
    

    Von der praktischen Umsetzung der Rotation-Animation abgesehen, wäre für mich Folgendes von Interesse:

    a) Wie kann ich mit Blick auf die drei Animationen in JS die animation-timing-function simulieren, sprich, statt eines streng linearen Ablaufs einen ease-in - Effekt für die Fade-In-Animation oder einen ease-out - Effekt für eine Fade-Out-Animation oder einen ease-in-out - Effekt für die Ladebalken- und die Rotation-Animation erzeugen?

    b) Wie kann ich aus der Fade-In-Animation - Funktion eine generell abrufbare 'Fade'-Animation - Funktion machen, mit der ich beliebige Elemente ein- ODER ausblenden kann - und dabei im Optimalfall noch über einen Parameter bestimmen kann, wie lange der Vorgang dauern soll?

    Abschließend, hat jemand praktische Erfahrung mit requestAnimationFrame ? Eine Alternative zu setInterval() oder setTimeout() ? Und falls ja, wie könnte man das an meinen Beispielen hier nutzen?

    Für Ideen, Hinweise und Anregungen wäre ich wie immer dankbar! ;)

    Soweit,

    Ahoi,

    Roadster.

    1. Hallo Roadster,

      Thema: Animieren mit JavaScript! :D

      ich würde, wenn eben möglich, Animationen per CSS durchführen, Stichworte transition und animation. Nach meiner Erfahrung laufen JS-Animationen viel zu "ruckelig". Start- und Endwerte kannst du ja mit JS setzen.

      Gruß, Jürgen

      1. Hallo Roadster,

        Hallo Jürgen!

        ich würde, wenn eben möglich, Animationen per CSS durchführen, Stichworte transition und animation. Nach meiner Erfahrung laufen JS-Animationen viel zu "ruckelig". [...]

        Stichwort: requestAnimationFrame()

        Du hast insofern recht, als dass setInterval() und setTimeout() tatsächlich nahezu zwangsläufig dazu führen, dass die Animationen "ruckelig" ablaufen, aber nachdem ich jetzt (ziemlich erfolgreich) mit requestAnimationFrame() herumexperimentiert habe, muss ich sagen, das ist ein Unterschied wie Tag und Nacht!

        Seit ich meine Animationsfunktionen mit requestAnimationFrame() aufrufe, laufen sie _butterweich_ ! Sogar noch flüssiger als mit CSS, wie mir scheint!

        Ruft man seine Animationsfunktion mit requestAnimationFrame() auf, landet man letztlich immer bei etwa 60 Iterationen pro Sekunde, was sehr geschmeidig ist und womit sich außerdem noch gut rechnen lässt.

        Der Unterschied ist wohl einfach, dass man den Browser mit setInterval() oder setTimeout() in einen starren Zeitplan drängt, der - man verzeihe mir meine laienhafte Ausdrucksweise - ganz offenbar den "natürlichen" Fluss des Programmablaufs hemmt, was dann zu Verzögerungen im Ablauf führt, wohingegen man mit requestAnimationFrame() dem Browser selbst die Entscheidung überlässt, wann 'genau' die nächste Iteration ausgespuckt wird, und die dazu nötige Rechenoperation dadurch sozusagen synchron zum "Fluss" des Programmablaufs eingebaut wird.

        Habe mich da mal ein wenig eingelesen und abgesehen davon, dass ich meine Animationen mittlerweile (inklusive "easing"-function) erfolgreich in reinem JS umgesetzt habe (mit Ausnahme der Rotation - da musste ich tatsächlich auf das CSSOM zurückgreifen - insoweit nur halbes JS ;) glaube ich, dass hinsichtlich Animationen in JS noch einiges an Potential steckt und während es wie gesehen zwar Dinge gibt, die im Moment mittels CSS noch besser handhabbar sind, gilt das so wie ich das sehe auch andersherum, - gerade wenn es um komplexere Berechnungen geht.

        Gruß,

        Roadster.

        1. Aloha ;)

          Bin tatsächlich positiv geflasht von den Möglichkeiten. Habe mich nach deinem Posting auch mal eingelesen, hier ein nützlicher Link:

          http://creativejs.com/resources/requestanimationframe/

          Allerdings muss ich dir ein klein wenig widersprechen. Das ist nicht soweit von CSS-Animationen entfernt wie du vielleicht denkst. Vielmehr ist es so, wie ich jetzt herausgelesen habe, dass requestAnimationFrame Zugriff auf dieselben nativen Methoden erhält, die auch von CSS-Animationen genutzt werden.

          Browsersupport sieht auch ganz gut aus, aber: für öffentlich zugängliche Projekte muss vorerst auf jeden Fall z.B. auf das unter dem Link ganz oben genannte Polyfill gesetzt werden (welches ja für fehlende Unterstützung auf setTimeout setzt), da IE9 keine Unterstützung bietet. IE9 ist aber noch bedeutsam, da es keine aktuellere IE-Version für Windows Vista gibt und der offizielle Support für Vista noch nicht eingestellt ist.

          Die Notwendigkeit, setTimeout einzusetzen, bleibt aber imho, wie der Artikel zeigt, dennoch - denn requestAnimationFrame ist nicht in der Lage, die Geschwindigkeit der Animation zu kontrollieren. Und damit bleibt für ease-Effekte auch die Notwendigkeit, komplizierte Funktionen einzusetzen, um die aktuelle Laufgeschwindigkeit anhand der gewünschten Laufdauer zu ermitteln.

          Grüße,

          RIDER

          --
          Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
          ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
          1. Aloha ;)

            Hallo RIDER :)

            Bin tatsächlich positiv geflasht von den Möglichkeiten. Habe mich nach deinem Posting auch mal eingelesen, hier ein nützlicher Link:

            http://creativejs.com/resources/requestanimationframe/

            Danke für den Tip! Interessante Lektüre ist immer willkommen! ;)

            Allerdings muss ich dir ein klein wenig widersprechen. Das ist nicht soweit von CSS-Animationen entfernt wie du vielleicht denkst. Vielmehr ist es so, wie ich jetzt herausgelesen habe, dass requestAnimationFrame Zugriff auf dieselben nativen Methoden erhält, die auch von CSS-Animationen genutzt werden.

            Wenn man erstmal eine Weile mit setInterval() /* oder */ setTimeout() an einem Ladebalken herumgewurschtelt hat und dann das Ganze mit requestAnimationFrame() durchlaufen lässt, erscheinen selbst die Erinnerungen an frühere CSS-Varianten holzschnittartig... :)

            Browsersupport sieht auch ganz gut aus, aber: für öffentlich zugängliche Projekte muss vorerst auf jeden Fall z.B. auf das unter dem Link ganz oben genannte Polyfill gesetzt werden (welches ja für fehlende Unterstützung auf setTimeout setzt), da IE9 keine Unterstützung bietet. IE9 ist aber noch bedeutsam, da es keine aktuellere IE-Version für Windows Vista gibt und der offizielle Support für Vista noch nicht eingestellt ist.

            Leute, die Windows Vista auf ihrem Rechner laufen haben verdienen es ohnehin nicht, berücksichtigt zu werden. ;)

            Die Notwendigkeit, setTimeout einzusetzen, bleibt aber imho, wie der Artikel zeigt, dennoch - denn requestAnimationFrame ist nicht in der Lage, die Geschwindigkeit der Animation zu kontrollieren. Und damit bleibt für ease-Effekte auch die Notwendigkeit, komplizierte Funktionen einzusetzen, um die aktuelle Laufgeschwindigkeit anhand der gewünschten Laufdauer zu ermitteln.

            var body = document.getElementsByTagName( "BODY" )[ 0 ];  
              
            fade( body, "fadeIn", 2 );
            

            Die "2" steht für 2 Sekunden, zumindest annäherungsweise, könnten auch 1 oder 5 sein...

            function fade( element, mode, duration ) {  
              
              var requestAnimationFrame = window.requestAnimationFrame ||  
                                          window.mozRequestAnimationFrame ||  
                                          window.webkitRequestAnimationFrame ||  
                                          window.msRequestAnimationFrame;  
              
              var d = duration * 60;  
              
              var iteration = 0;  
              
              var t;  
              
              
              if ( mode === "fadeIn" ) {  
              
                fadeIn();  
              
              }  
              
              
              function fadeIn() {  
              
                t = easeIn( iteration, 0, 100, d );  
              
                iteration++;  
              
                var opacity = t / 100;  
              
                element.style.opacity = opacity + "";  
              
                if ( opacity <= 100 ) {  
              
                  requestAnimationFrame( fadeIn );  
              
                }  
              
                else {  
              
                  element.style.opacity = "1";  
              
                }  
              
              }  
              
              function easeIn( c, s, l, t ) {  
              
                return l * Math.pow( c / t, 3 ) + s;  
              
              }  
              
            }
            

            ;)

            Gruß,

            Roadster.

            1. Sorry, hab mich vertippt:

              Soll heißen... "z"

                function easeIn( c, s, l, z ) {  
                
                  return l * Math.pow( c / z, 3 ) + s;  
                
                }
              

              ... "t" hatten wir ja schon ;)

              Gruß,

              Roadster.

            2. Herrje!

              Die "2" steht für 2 Sekunden, zumindest annäherungsweise, könnten auch 1 oder 5 sein...

              Ich sollte mich präziser ausdrücken! :D

              Damit meine ich natürlich nicht, dass wenn man 2 Sekunden als Wert für den Parameter "duration" angibt, die Animation dann trotzdem 1 oder 5 Sekunden dauern könnte...

              ...sondern, dass man _auch_ andere Werte, wie 1 _oder_ 5 oder [n] eingeben könnte und die tatsächliche Dauer der Animation dann ziemlich genau diesem Wert entspricht. :D

              Sorry sorry sorry! ;)

              Gruß,

              Roadster.

              1. Aloha ;)

                Damit meine ich natürlich nicht, dass wenn man 2 Sekunden als Wert für den Parameter "duration" angibt, die Animation dann trotzdem 1 oder 5 Sekunden dauern könnte...

                ...sondern, dass man _auch_ andere Werte, wie 1 _oder_ 5 oder [n] eingeben könnte und die tatsächliche Dauer der Animation dann ziemlich genau diesem Wert entspricht. :D

                Letzteres hängt aber ganz, ganz wesentlich davon ab, ob die Funktion tatsächlich genau mit 60 fps getaktet ist. Ich bin mir noch nicht ganz sicher, ob das tatsächlich und immer gewährleistet ist.

                Ansonsten (und meine eben genannten Bedenken kann man bei deinem Projekt sowieso über Bord werfen) finde ich deine Methode recht elegant.

                Support für IE9 über setTimeout-Fallback bietet deine Methode aber nicht :P

                Ceterum censeo Windows Vista Internet Explorer Neunque esse delendam.

                Grüße,

                RIDER

                --
                Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
                ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
                1. Aloha ;)

                  Hallo RIDER :)

                  Letzteres hängt aber ganz, ganz wesentlich davon ab, ob die Funktion tatsächlich genau mit 60 fps getaktet ist. Ich bin mir noch nicht ganz sicher, ob das tatsächlich und immer gewährleistet ist.

                  Das ist mir klar und ich bin mir da ebenfalls nicht sicher!  ;)  Auf meinem Rechner stimmt es zwar fast 1:1, aber der ist high-end. Man müsste die Funktion mal einem richtig üblen Stresstest unterziehen und schauen, was dabei herumkommt...

                  Es erschien mir in meiner Situation halt einfach praktikabel es so zu machen, aber ob es auch generell zu empfehlen ist, sei doch erstmal dahingestellt. :/

                  An Ende müsste man vielleicht doch noch eine Korrekturfunktion einbauen...

                  Naja, mal schauen, vielleicht finden sich ja auch im Internet praktische Erfahrungswerte - dann sind wir schlauer. :)

                  Gruß,

                  Roadster.

                  1. Aloha ;)

                    Es erschien mir in meiner Situation halt einfach praktikabel es so zu machen, aber ob es auch generell zu empfehlen ist, sei doch erstmal dahingestellt. :/

                    An Ende müsste man vielleicht doch noch eine Korrekturfunktion einbauen...

                    Naja, mal schauen, vielleicht finden sich ja auch im Internet praktische Erfahrungswerte - dann sind wir schlauer. :)

                    Mir erschien der unter oben verlinkten Artikel genannte Ansatz, die seit Start der Animation verstrichene Zeit für die Determinierung des Animationsschritts zu nutzen, relativ sinnvoll. Das schließt Frame-dropping und timing-Probleme eigentlich nahezu aus. Fand ich recht elegant.

                    Grüße,

                    RIDER

                    --
                    Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
                    ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
                    1. Aloha ;)

                      Hallo RIDER :)

                      Mir erschien der unter oben verlinkten Artikel genannte Ansatz, die seit Start der Animation verstrichene Zeit für die Determinierung des Animationsschritts zu nutzen, relativ sinnvoll. Das schließt Frame-dropping und timing-Probleme eigentlich nahezu aus. Fand ich recht elegant.

                      In der Tat!

                      Mit Netz und doppeltem Boden.

                      Ich bin fast geneigt, auch noch ein fallback für Nutzer inadäquater Software zu implementieren.

                      Fast. ;)

                      Nochmal Danke für den Tip!

                      Gruß,

                      Roadster.

    2. Aloha ;)

      Thema: Animieren mit JavaScript! :D

      Ich habe im Prinzip drei Arten von CSS-Animationen, die ich gerne in JavaScript simulieren möchte:

      Nett. Du machst das, was man jetzt mit CSS machen kann, mit JavaScript - so wie wir das schon vor 10 Jahren mangels CSS-Möglichkeiten gemacht haben ;) Nostalgie...

      Aber: Warum eigentlich dieser Rückschritt?

      Zur Rotation: Animation: Das ist imho nicht sinnvoll zu lösen, da dir schlicht die proprietären Werkzeuge dafür in JavaScript fehlen. Es wird dir allenfalls möglich sein, eine verhältnismäßig schlechte Nachahmung des Effekts umzusetzen. Zumindest wenn du auf CSS3 verzichten willst a la retro. Mit Einsatz von CSS3 ist es genauso einfach zu lösen wie die anderen beiden.

      Von der praktischen Umsetzung der Rotation-Animation abgesehen, wäre für mich Folgendes von Interesse:

      a) Wie kann ich mit Blick auf die drei Animationen in JS die animation-timing-function simulieren, sprich, statt eines streng linearen Ablaufs einen ease-in - Effekt für die Fade-In-Animation oder einen ease-out - Effekt für eine Fade-Out-Animation oder einen ease-in-out - Effekt für die Ladebalken- und die Rotation-Animation erzeugen?

      Das kommt auch ein bisschen auf die erwünschte Komplexität an. CSS arbeitet mit der Bezierkurve. Die kann man in JavaScript nachbilden. Die Werte aus der Bezierkurve bestimmen letztendlich den Step. Das erzeugt dann letztendlich den selben Effekt. Es geht aber auch mit einfacheren Funktionen einfacher, wenn man etwas weniger Wert auf Geschmeidigkeit legt.

      b) Wie kann ich aus der Fade-In-Animation - Funktion eine generell abrufbare 'Fade'-Animation - Funktion machen, mit der ich beliebige Elemente ein- ODER ausblenden kann - und dabei im Optimalfall noch über einen Parameter bestimmen kann, wie lange der Vorgang dauern soll?

      Du könntest in einer Fade-Funktion per Timeout oder Intervall festlegen, dass zeitlich nach Ende der fade-In-Animation die fade-Out-Animation abgespielt wird.

      Noch besser: du programmierst eine fade-Animation, die bis 100% hochzählt und danach intern umschaltet. Also in etwa eine

      function fade (element,step,duration,counter) {...}

      element,step,duration bleiben gleich, counter wird immer um 1 erhöht. Die Opacity ergibt sich dann aus der counter-Variable:

      element.style.opacity = ((counter % 200 > 100)?(100-counter % 100):(counter % 100)) / 100;

      Die Animation soll dann laufen bis duration < counter * step.

      Wenn du z.B. per Bezierkurve noch die Geschwindigkeit kontrollierst brauchst du statt step eine andere variable v zum Übergeben, die die Länge einer Teilanimation angibt (als Parameter für die Bezierkurve) und die Abbruchbedingung muss sich dann aus duration < v*(100 - counter % 100)/100 + x zusammensetzen, wobei sich x aus der Bezierkurve berechnet und die vergangene Dauer im aktuellen Zyklus angeben...

      Abschließend, hat jemand praktische Erfahrung mit requestAnimationFrame ? Eine Alternative zu setInterval() oder setTimeout() ? Und falls ja, wie könnte man das an meinen Beispielen hier nutzen?

      Nö, hab ich leider noch nicht. Meine praktischen Fertigkeiten sind etwas eingerostet, als ich das letztemal mit JS-Animationen zu tun hatte gabs weder CSS3 noch requestAnimationFrame. Ich glaube aber, dass das die sinnvollere Möglichkeit ist. An meinen Ausführungen oben erkennst du, dass es extremst aufwändig ist, das Rad neu zu erfinden. Lieber soviel wie möglich vorhandenes nutzen.

      Grüße,

      RIDER

      --
      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
      ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
      1. Aloha ;)

        Hallo RIDER :)

        Aber: Warum eigentlich dieser Rückschritt?

        Zwanghafte Persönlichkeitsstörung.

        Ich leide unter der Zwangsvorstellung, einfach ALLES in JavaScript schreiben zu müssen. Oder zumindest alles, was möglich ist. Bis zum Äußersten. ;)

        Meine HTML-Datei sieht dementsprechend etwa so aus...

        <html>  
          <head>  
          
           <!-- title meta blabla -->  
          
           <style>  
          
           .animation1 {  
          
            /*...*/  
          
           }  
          
           .animation2 {  
          
            /* ... */  
          
           }  
          
           </style>  
          </head>  
          <body>  
          <script>  
          
          window.addEventListener("load", loadProgram);  
          
          function loadProgram() {  
          
          /* ... */  
          
          }  
          
          function createElements() {  
          
          /* ... */  
          
          }  
          
          /*  ...3000 Zeilen Script... */  
          
          </script>  
          <div id="library">  
          
          <!-- 5000 Zeilen Text-Content -->  
          
          </div>  
         </body>  
        </html>
        

        ...und das Programm läuft wie geschmiert!!! :)

        Aber vielleicht isses doch behandlungsbedürftig... wer weiß.

        Zur Rotation: Animation: Das ist imho nicht sinnvoll zu lösen, da dir schlicht die proprietären Werkzeuge dafür in JavaScript fehlen. Es wird dir allenfalls möglich sein, eine verhältnismäßig schlechte Nachahmung des Effekts umzusetzen. Zumindest wenn du auf CSS3 verzichten willst a la retro. Mit Einsatz von CSS3 ist es genauso einfach zu lösen wie die anderen beiden.

        Gibt es die Möglichkeit CSS Animationen direkt in JS zu erstellen? - Wäre zwar nicht 'echt', aber ich glaube, damit könnte ich leben!

        Der Rest liest sich erstmal so, als sollte ich doch mit der Beschäftigung damit bis _nach_ meiner Klausur warten.. ;)

        Vielen Dank für die Infos!

        Gruß,

        Roadster.

        1. Aloha ;)

          Gibt es die Möglichkeit CSS Animationen direkt in JS zu erstellen? - Wäre zwar nicht 'echt', aber ich glaube, damit könnte ich leben!

          Muss ich passen, keine Ahnung. Aus dem Bauch heraus: Manipuliere per JavaScript
          die Klassenzugehörigkeit und lass die Animation über die CSS-Klasse ablaufen.

          Keine Ahnung ob das funktioniert oder obs noch besser geht ;)

          Möglich, dass ich das mal noch für dich recherchiere...

          Der Rest liest sich erstmal so, als sollte ich doch mit der Beschäftigung damit bis _nach_ meiner Klausur warten.. ;)

          Ja, definitiv ;)

          Grüße,

          RIDER

          --
          Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
          ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
          1. Aloha ;)

            Hallo RIDER :)

            Muss ich passen, keine Ahnung. Aus dem Bauch heraus: Manipuliere per JavaScript
            die Klassenzugehörigkeit und lass die Animation über die CSS-Klasse ablaufen.

            Wenn es das ist, was du meinst...

            .fadeIn {  
              
              animation-name: fadeInMov;  
              animation-duration: 0.8s;  
              animation-iteration-count: infinite;  
              animation-play-state: paused;  
              animation-timing-function: ease-in;  
              
            }  
            @keyframes fadeInMov {  
              
               0% {opacity:0;}  
             100% {opacity:1;}  
              
            }
            

            ...und...

            function startAnimation(element,animation) {  
              
              if (animation == "fadeIn") {  
              
                element.style.display = "block";  
              
              }  
              
              element.className = animation;  
              
              element.style.animationPlayState = "running";  
              
            }
            

            ...naja, so mach' ich's ja bisher.

            Keine Ahnung ob das funktioniert oder obs noch besser geht ;)

            Funktionieren tut es sicherlich. Mit CSS. ;)

            Möglich, dass ich das mal noch für dich recherchiere...

            Naa, mach dir da mal keine Arbeit, wenn ich Zeit habe, kann ich auch selbst nochmal nachschauen.

            Sonst. Hmm. Naja. Eigentlich ist es gar nicht mal JavaScript selbst, dass mich so übermäßig reizt und mich wider besseren Wissens so handeln lässt... Ich mag CSS. Und HTML ist ansich auch Ok. Was mich innerlich umtreibt ist diese elende Uneinheitlichkeit...

            Ich meine, da ist diese Vorstellung von Einheit, Geschlossenheit, Makellosigkeit, ... eine Datei, eine Sprache, ein Programm, ... Klarheit im Ausdruck, reine Logik.

            Definitiv behandlungsbedürftig! :D

            Also,

            Nochmal vielen Dank!

            Gruß,

            Roadster.

        2. Hakuna matata!

          Gibt es die Möglichkeit CSS Animationen direkt in JS zu erstellen? - Wäre zwar nicht 'echt', aber ich glaube, damit könnte ich leben!

          Ja, ähnlich zu dem, was das DOM für HTML ist, gibt es das CSSOM für CSS. Damit kannst Stylesheets programmatisch erzeugen. Die API ist aber verglichen mit dem DOM sehr unausgereift, sehr viele Regeln haben keine Repräsentation als Objekt, sondern müssen als plane Strings formuliert werden.

          Wenn es etwas mehr sein darf oder wenn du auch bloß nach Inspiration suchst, wie du mit JavaScript auf elegante weise CSS modellieren kannst, dann wirf mal einen Blick af AbsurdJS. Das ist ein Preprozessor, ähnlich wie SASS oder LESS, nur dass das Eingabeformat selbst JavaScript ist, es wird also JavaScript-Code in CSS-Code übersetzt.

          --
          “All right, then, I'll go to hell.” – Huck Finn
          1. Hakuna matata!

            Hallo 1UnitedPower!

            Gibt es die Möglichkeit CSS Animationen direkt in JS zu erstellen? - Wäre zwar nicht 'echt', aber ich glaube, damit könnte ich leben!

            Ja, ähnlich zu dem, was das DOM für HTML ist, gibt es das CSSOM für CSS. Damit kannst Stylesheets programmatisch erzeugen. Die API ist aber verglichen mit dem DOM sehr unausgereift, sehr viele Regeln haben keine Repräsentation als Objekt, sondern müssen als plane Strings formuliert werden.

            Wenn es etwas mehr sein darf oder wenn du auch bloß nach Inspiration suchst, wie du mit JavaScript auf elegante weise CSS modellieren kannst, dann wirf mal einen Blick af AbsurdJS. Das ist ein Preprozessor, ähnlich wie SASS oder LESS, nur dass das Eingabeformat selbst JavaScript ist, es wird also JavaScript-Code in CSS-Code übersetzt.

            Danke für die Infos! Klingt jedenfalls schonmal vielversprechend. Insbesondere "AbsurdJS" klingt wie für mich geschaffen! :D

            Kann's nicht erwarten, meine verdammte Klausur entlich hinter mich zu bringen und mal wieder etwas Freizeit zu haben, sieht so aus, als wenn es hier doch ein breites Feld gibt, auf dem ich mich austoben kann! ;)

            Nochmal Danke!

            Gruß,

            Roadster.

  3. Hallo miteinander!

    Habe noch was gefunden, zu dem mich mal eure Einschätzungen interessieren würden, wobei ich die Diskussion über die Zweckmäßigkeit der Grundprämisse selbst mal außen vor lassen möchte, - also stellt euch das am besten einfach als hypothetische Situation vor. ;)

    Wie schon in einigen Posts von mir beschrieben, generiere ich die Elemente meiner Seite komplett mit JavaScript, was an und für sich auch völlig unproblematisch ist. Die Frage, die ich mir aber stelle ist, wie ich das am besten notiere. Bislang hatte ich für jedes Element eine eigene Funktion, das heißt, im Script sieht das im Moment noch etwa so aus...

    function createElement() {  
      
      var parent = document.getElementById( "parent" ),  
          element = document.createElement( "TAG" );  
      
      parent.appendChild( element );  
      
      element.id = "element";  
      
      element.style.display = "block";  
      
      element.style.position = "relative";  
      element.style.margin = "10px auto 0px";  
      element.style.width = "200px";  
      element.style.height = "50px";  
      
      element.style.cursor = "pointer";  
      
      element.style.border = "2px solid black";  
      element.style.borderRadius = "5px";  
      
      /* etc. etc. etc. */  
      
    }
    

    Der Vorteil darin es so zu machen, ist natürlich der, dass der Code für die Elementerstellung extrem gut lesbar ist, sprich, man sieht auf den ersten Blick wie in einer CSS-Datei sofort alle wichtigen Eigenschaften des Elementes vor sich (was ich noch dadurch unterstützt habe, dass ich für die Notation der style-Attribute eine festgelegte Reihenfolge und eigenschaftsbezogene Gruppierung verwende).

    Der Nachteil an dieser Methode ist demgegenüber aber natürlich, dass der Code auch bei einer an und für sich recht überschaubaren Menge an generierten Elementen ziemlich lang wird, wobei die verwendeten Attribute jedoch sehr oft gleich bleiben ( element.style.position = "relative"; ), gegebenenfalls halt nur mit veränderten Werten.

    Zu überlegen wäre demnach, ob man das nicht verkürzen kann (und vor allem sollte), indem man sowohl die Elemente als auch die Werte für bestimmte Attribute, in Arreys zwischenspeichert, um sie dann in generalisierten Funktionen zusammenzubringen. Also, sprich, statt linear vorzugehen und ein Element nach dem anderen zu erstellen, könnte man ja auch quasi in einer hierarchischen Funktion von 'oben herab' über for-Schleifen die Elemente erstellen und stylen...

    Ich schätze, damit würde ich wohl locker 80% Code für die "createElement"-Funktionen einsparen. Aber womöglich auch 80% der Lesbarkeit?  ;)  Welche Variante haltet ihr für vorzugswürdig?

    Gruß,

    Roadster.