Rudolf: CSS-Klassen Werte in Javascript auslesen?

Hallo und schönen Sonntag!

Ich versuche gerade, via Javascript die Werte einer aus einem externen Stylesheet geladenen Klasse auszulesen - geht das?

.animation {
	transition: all 0.5s linear;
}
 * * * Javascript Magic * * *

...soll mir also den String transition: all 500ms linear zurückgeben.

...um ganz genau zu sein, bräuchte ich eigentlich nur den all 0.5s linear Teil, das sollte dann aber ja kein Problem mehr sein

LG, Rudolf

  1. Sorry, soll natürlich transition: all 0.5s linear zurückgeben.

  2. Erster Treffer in der Suchmaschine ("js read from css class")

    https://stackoverflow.com/questions/324486/how-do-you-read-css-rule-values-with-javascript

    1. Tatsächlich :O

      Aber muss ich auch über sämtliche SelectorTexte im Stylesheet iterieren, wenn einem Element im DOM die Klasse bereits zugewiesen wurde? In meinem Fall:

      Im Stylesheet:

      .animation {
      	transition: all 0.5s linear;
      }
      

      Im Dokument:

      <section id="holder" class="side animation">
      

      Da scheint es mir ein wenig ...umständlich und nicht sehr ressourcenschonend über das gesamte Stylesheet zu iterieren.

      Andererseits erscheint es auch wieder logisch, weil sich die Klasse auf das Stylesheet bezieht und ich sie daher dort [wahrscheinlich?] auch suchen muss.

      Gruß, Rudolph

      1. Da scheint es mir ein wenig ...umständlich und nicht sehr ressourcenschonend über das gesamte Stylesheet zu iterieren.

        Andererseits erscheint es auch wieder logisch, weil sich die Klasse auf das Stylesheet bezieht und ich sie daher dort [wahrscheinlich?] auch suchen muss.

        Die Frage ist, was Du GENAU willst:

        Übrigens kommt es hinsichtlich der Preformance sehr darauf an, wie groß und kompliziert der Stylesheet ist. Spätestens wenn Du auch „@media“ zu berücksichtigen hast, kann es sein, dass nur die Lösung von Rolf zu brauchbaren Ergebnissen führt.

  3. Hallo Rudolf,

    bei dieser Aktion kann es schnell zu Missverständnissen kommen.

    Willst Du:

    • in deinem Stylesheet / deinen Stylesheets eine Regel für die Klasse animation finden und darin die Einstellung für die transition Eigenschaft auslesen? Darauf passt der Raketenhinweis. Probleme:

      • Es mag mehr als ein Stylesheet mit dieser Regel geben, und es kann sogar in einem einzigen Stylesheet mehrere Regeln geben, die die Klasse animation beeinflussen. Entweder durch Kombinatoren (li .animation oder #foo .animation oder .animation:first-of-type() oder oder oder) oder durch Media-Abfragen. Sowas ist dann nicht mal falsch, sondern die Eintellungen gelten dann für unterschiedliche Kontexte.
      • Dass die Klasse .animation diese transition-Eigenschaft setzt, bedeutet noch nicht, dass ein Element mit dieser Klasse diese Eigenschaft auch bekommt. Es kann auch noch andere Style-Regeln geben, die eine ganz andere transition verordnen. Wenn für ein Element dann Regeln zutreffen, gewinnt die mit der höheren Spezifiziät.
    • für ein konkretes Element im DOM feststellen, welche transition-Eigenschaft dafür gilt? Dafür suchst Du dir dieses Element heraus und rufst

    window.getComputedStype(element);
    

    auf, um den zu diesem Zeitpunkt gültigen Style für dieses Element zu finden. Über Spezifizität kann sich dann der Browser den Kopf die CPU zerbrechen.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rudolf,

      bei dieser Aktion kann es schnell zu Missverständnissen kommen.

      Willst Du:

      • in deinem Stylesheet / deinen Stylesheets eine Regel für die Klasse animation finden und darin die Einstellung für die transition Eigenschaft auslesen? Darauf passt der Raketenhinweis. Probleme:
        • Es mag mehr als ein Stylesheet mit dieser Regel geben,

      sollte eigentlich mit document.styleSheets[0].rules kein Problem sein - in dem Fall sollte ich eindeutig das erste Stylesheet referenzieren.

      und es kann sogar in einem einzigen Stylesheet mehrere Regeln geben, die die Klasse animation beeinflussen. Entweder durch Kombinatoren (li .animation oder #foo .animation oder .animation:first-of-type() oder oder oder) oder durch Media-Abfragen. Sowas ist dann nicht mal falsch, sondern die Eintellungen gelten dann für unterschiedliche Kontexte.

      Hm... auch das sollte eigentlich kein Problem sein...? Setzt man die am meisten für gut erachtete Lösung des von Raketensuchradar dankenswerterweise zur Verfügung gestellten Links um (die von nsdel), dann bezieht sich dort getStyle('.test') exklusiv auf die Klasse test. Ich hab das durchgespielt und ausprobiert - hast du (wie in meinem Fall) eine Klasse .animation mit transition: all 0.5s linear und gleichzeitig z.B. #foo .animation, dann spuckt getStyle('.animation') ersteres und getStyle('#foo .animation') zweiteres aus. Aber vielleicht habe ich dich da missverstanden.

      Dass die Klasse .animation diese transition-Eigenschaft setzt, bedeutet noch nicht, dass ein Element mit dieser Klasse diese Eigenschaft auch bekommt. Es kann auch noch andere Style-Regeln geben, die eine ganz andere transition verordnen. Wenn für ein Element dann Regeln zutreffen, gewinnt die mit der höheren Spezifiziät.

      Ja ne, is klar 🙃

      Gruß Rudolph.

    2. @@Rolf B

      Es mag mehr als ein Stylesheet mit dieser Regel geben

      Das wird in der ersten Antwort berücksichtigt.

      und es kann sogar in einem einzigen Stylesheet mehrere Regeln geben, die die Klasse animation beeinflussen. Entweder durch Kombinatoren (li .animation oder #foo .animation oder .animation:first-of-type() oder oder oder)

      Und keine dieser Regeln wird gefunden. Und auch nicht .foo, .animation {}.

      if (classes[x].selectorText == className_) ist falsch; es darf nicht auf Gleichheit geprüft werden, sondern ob der fragliche Selektor className_ in classes[x].selectorText enthalten ist.

      Seltsame Benennung mit dem _ am Ende.

      Und die Benennung var classes = styleSheets[i].rules || styleSheets[i].cssRules ist auch falsch. Der Ausdruck auf der rechten Seite liefert CSS-Regeln; das können Regeln für Klassenselektoren sein oder auch für Elementtyp-Selektoren oder ID-Selektoren o.a. Die Variablenbezeichnung classes ist unpassend.

      Für welche Uralt-Browser ist eigentlich styleSheets[i].rules gedacht?


      für ein konkretes Element im DOM feststellen, welche transition-Eigenschaft dafür gilt? Dafür suchst Du dir dieses Element heraus und rufst

      window.getComputedStype(element);
      

      auf, um den zu diesem Zeitpunkt gültigen Style für dieses Element zu finden. Über Spezifizität kann sich dann der Browser den Kopf die CPU zerbrechen.

      Ja, vermutlich besser – aber immer noch nicht gut.

      🖖 Stay hard! Stay hungry! Stay alive! Stay home!

      --
      Home Office ist so frustierend, weil man jetzt noch viel stärker bemerkt mit wievielen Menschen man zu tun hat, die nicht sinnerfassend lesen können. (@Grantscheam)
      1. if (classes[x].selectorText == className_) ist falsch; es darf nicht auf Gleichheit geprüft werden, sondern ob der fragliche Selektor className_ in classes[x].selectorText enthalten ist.

        Das verstehe ich nicht ganz. Produziert selectorText nicht quasi den selectorText selbst?

        Also quasi so wie z.B. Object.keys(obj) explizit Key und nicht Value zurückgibt. (Jaja, mir schwant schon, ÜBLER Vergleich...)

        Wenn nicht verstehe ich aber, was du meinst. Wie überprüfe ich dann, ob className ( vielleicht besser eher selektorName ) in selectorText enthalten?

        Und die Benennung var classes = styleSheets[i].rules || styleSheets[i].cssRules ist auch falsch. Der Ausdruck auf der rechten Seite liefert CSS-Regeln; das können Regeln für Klassenselektoren sein oder auch für Elementtyp-Selektoren oder ID-Selektoren o.a. Die Variablenbezeichnung classes ist unpassend.

        Kam mir auch in den Sinn, als ich die Lösung sah 😄

        1. Hallo,

          if (classes[x].selectorText == className_) ist falsch; es darf nicht auf Gleichheit geprüft werden, sondern ob der fragliche Selektor className_ in classes[x].selectorText enthalten ist.

          Das verstehe ich nicht ganz. Produziert selectorText nicht quasi den selectorText selbst?

          ja, eben. Den einen Knackpunkt hast du in deinem zweiten Posting schon angesprochen, den zweiten Punkt[!] hast du anscheinend noch nicht gesehen: selectorText enthält, wie der Name sagt, den gesamten Selektor. Im Fall eines Klassenselektors ist das aber nicht nur der Klassenname, sondern auch noch der Punkt davor.

          Und mir ist immer noch schleierhaft, was du mit diesen Purzelbäumen eigentlich erreichen willst - zumal du alle Hinweise auf Unzulänglichkeiten mit "das ist aber sogar ein Vorteil" abtust.

          Live long and pros healthy,
           Martin

          --
          Ich stamme aus Ironien, einem Land am sarkastischen Ozean.
          1. Hallo Martin,

            ich möchte einfach die Zeit der transition zur Verfügung haben, damit ich dann on the fly bestimmen kann wann darauf folgendes, vorhergehende ABER AUCH GLEICHZEITIGE Vorgänge passieren. Dazu benötige ich jedenfalls den Zeitstempel der Transition.

            ...oft ist es am Ende eines Projekts ja so, dass man die ein oder andere Sache noch tweaked - und wenn ich dann z.B. diese Transition doch als zu langwierig empfinde, möchte ich sie einfach updaten können, ohne dass mein gesamter Code über mir zusammenbricht.

            Gruß Rudolph.

      2. if (classes[x].selectorText == className_) ist falsch; es darf nicht auf Gleichheit geprüft werden, sondern ob der fragliche Selektor className_ in classes[x].selectorText enthalten ist.

        NACHTRAG

        Okay, ich verstehe, was du meinst! 🙉

        Kette ich mehrere Selektoren aneinander, funktioniert der Code so nicht mehr.

        ...ist aber in meinem Fall sogar erwünscht, da ich so sicher sein kann, dass explizit nur .animation angesprochen wird und eben nicht #foo .animation o. ä.

        Gruß Rudolph

        1. Hallo Rudolph,

          in deinem konkreten Fall mag das erwünscht sein. Aber versteife Dich bitte nicht auf das Auslesen der Rules und deren Interpretation. Das kann schnell komplex werden. Du sprichst ja selbst von konsekutiven und parallelen Aktionen. Was ist mit

          #foo .animation { transition: ... 3s ...; }
          #bar .animation { transition: ... 2s ...; }
          

          Hier reicht die Suche nach "animation" nicht - die reicht sowieso nicht:

          .no-animation { transition: none; }
          .animationDemo { transition: ...4s...; }
          

          oder noch schlimmer - das schmeißt auch Gunnar aus der Kurve:

          #foo :not(.animation) { ... }
          

          Mit anderen Worten: Damit dein JS funktioniert, musst Du Dir genaue Regeln setzen, wie Du dein CSS gestalten darfst. Not Good, wie Happy Quinn zu sagen pflegt.

          Ich gehe davon aus, dass Du für deine Synchronisierungen das Animationsverhalten eines konkreten Elements betrachten musst, und dann ist window.getComputedStyle(element) auf jeden Fall die bessere Lösung.

          Anstatt Dir das Animationstiming aus den CSS Rules zusammenzufrickeln, könntest Du auch die entsprechenden Events nutzen: transitionrun, transitionstart und transitionend. Damit bekommst Du Bescheid, wenn was passiert, und musst es nicht ausrechnen. Unser Wiki scheint dazu nichts zu haben, aber bei MDN gibt's Beispiele und Referenzinformationen.

          Wenn es um parallele Aktionen geht, kann man das ggf. auch durch das Teilen von Animationen in mehrere Abschnitte per Event steuern - aber da muss nicht funktionieren.

          Und es gibt außer Transitionen auch noch die Animationen. Auch die haben Events, und mit keyframes geht viel mehr als mit einfachen Transitionen.

          Im allerübelsten Fall animiert man doch per JavaScript und requestAnimationFrame, aber das ist wirklich nur die letzte Rettung wenn man die Synchro gar nicht anders hinbekommt.

          Rolf

          --
          sumpsi - posui - obstruxi
  4. @@Rudolf

    Ich versuche gerade, via Javascript die Werte einer aus einem externen Stylesheet geladenen Klasse auszulesen - geht das?

    Was hast du damit vor?

    Mich deucht, dass was immer du erreichen willst, auf anderem Weg zu erreichen sein sollte.

    🖖 Stay hard! Stay hungry! Stay alive! Stay home!

    --
    Home Office ist so frustierend, weil man jetzt noch viel stärker bemerkt mit wievielen Menschen man zu tun hat, die nicht sinnerfassend lesen können. (@Grantscheam)