Don P: CSS-Eigenschaft dynamisch ändern für Elemente mit class=

Hallo Leute,

Folgendes ist gegeben:

Eine Tabelle, in der alle Zellen im <tbody> mit einem Attribut class="spalteX"  versehen sind (mit X = 1...n Tabellenspalten). Die Tabelle ist standardmäßig nach der 1. Spalte sortiert und dementspechend existiert im CSS-Stylesheet die Angabe

.spalte1 {font-weight:bold;}

Durch Klicken auf eine Spaltenüberschrift <th> wird die Tabelle entsprechend den Inhalten der geklickten Spalte von meinem Script umsortiert und neu dargestellt. Schön, schön.

Das Problem:

Es gelingt mir nicht, die style-Definition für alle Elemente mit class="spalte1" von bold auf normal umzustellen und dafür die Elemente der sortierten Spalte z.B. mit class="spalte3" fett zu formatieren.

Nach allem, was ich in SELFHTML dazu gefunden habe, geht das nur im IE über document.all oder sonst durch Abklappern jeder einzelnen Zelle der umzuformatierenden Spalten.

Gibt es wirklich keinen besseren, browserübergreifenden Weg? Man müsste doch irgendwie direkt auf die CSS-Definition für eine bestimmte class zugreifen und diese ändern können, so dass auf einen Schlag alle Elemente mit dem entsprechenden class-Attribut die neue Style-Eigenschaft zeigen.

Kann mir da jemand auf die Sprünge helfen?

Vielen Dank,
Don P

  1. Hallo,

    durch Abklappern jeder einzelnen Zelle der umzuformatierenden Spalten.

    Das wäre die umständlichste Lösung.

    Man müsste doch irgendwie direkt auf die CSS-Definition für eine bestimmte class zugreifen und diese ändern können

    Das ist möglich, aber auch ziemlich umständlich.

    Eine bessere Lösung wäre es, einfach die Klasse der Tabelle zu ändern. Durch entsprechende Style-Regeln wird dann die jeweilige Spalte umformatiert:

    .spalte1aktiv .spalte1, .spalte2aktiv .spalte2, .spalte3aktiv .spalte3, ... { font-weight:bold; }

    Das Problem ist nur, dass diese Auflistung lang werden kann, je nachdem, wieviel Spalten du hast.

    Mathias

    1. Hallo,

      Man müsste doch irgendwie direkt auf die CSS-Definition für eine bestimmte class zugreifen und diese ändern können

      Das ist möglich, aber auch ziemlich umständlich.

      Wie würde das dann gehen? Vielleicht durch Ändern der .innerHTML-Eigenschaft des eines im Dokumentkopf notierten <style>-Elements? Das wollte ich als nächstes ausprobieren, aber ich fürchte, dass die Änderung dann nicht sofort wirkt, sondern das ganze Dokument erst irgendwie neu gerendert werden muss.

      Eine bessere Lösung wäre es, einfach die Klasse der Tabelle zu ändern. Durch entsprechende Style-Regeln wird dann die jeweilige Spalte umformatiert:

      .spalte1aktiv .spalte1, .spalte2aktiv .spalte2, .spalte3aktiv .spalte3, ... { font-weight:bold; }

      Ach ja, daran habe ich noch gar nicht gedacht :-).

      Das Problem ist nur, dass diese Auflistung lang werden kann, je nachdem, wieviel Spalten du hast.

      Es sind derzeit nur drei Spalten, wäre also machbar. Lieber wäre mir natürlich eine allgemeine Methode, die sich auf jede denkbare Tabelle anwenden lässt.

      Vielen Dank, Don P

      1. Hallo,

        Man müsste doch irgendwie direkt auf die CSS-Definition für eine bestimmte class zugreifen und diese ändern können

        Das Stichwort lautet document.styleSheets.
        Cybaer hat da mal eine Helferfunktion geschrieben: http://coding.binon.net/dhtml/cssrule.htm

        Mathias

        1. Hallo,

          Man müsste doch irgendwie direkt auf die CSS-Definition für eine bestimmte class zugreifen und diese ändern können

          Das Stichwort lautet document.styleSheets.

          Danke, das hat geholfen! Ergebnis:

            
          var setTblColStyle = function(nSheet, strClass, strProperty, strPropval) {  
            
              var oStyleSheet = document.styleSheets[nSheet];  
              var arrRules = oStyleSheet.cssRules || oStyleSheet.rules; // oStyleSheet.rules for IE only  
            
              for (var i = 0; i < arrRules.length; i++) {  
            
                  var oRule = arrRules[i];  
                  oRule.style[strProperty] = oRule.selectorText === strClass ? strPropval : '';  
              }  
          };  
            
          // Aufzurufen z.B. mit:  
          setTblColStyle(0, '.spalte2', 'fontWeight', 'bold');
          

          Cybaer hat da mal eine Helferfunktion geschrieben: http://coding.binon.net/dhtml/cssrule.htm

          Wow, die ist mit 222 Zeilen ja wirklich gigantisch, kann aber auch wesentlich mehr als meine. Meine hier tut's zumindest in neueren FFs und IEs, vermutlich auch in Opera, das sollte erst einmal reichen...

          Gruß, Don P

          1. @@Don P:

            Wow, die ist mit 222 Zeilen ja wirklich gigantisch

            Eben.

            Wann immer der Hinweis auf Cybaers Spatzenkanone kommt, sollte dabei auch darauf hingewiesen werden, dass es oft unsinnig ist, diese anzuwenden.

            Warum bist du nicht der wesentlich „besseren Lösung“ aus molilys erstem Posting gefolgt?

            Live long and prosper,
            Gunnar

            --
            „Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann.“ (Joseph Weizenbaum)
            1. Hallo,

              Warum bist du nicht der wesentlich „besseren Lösung“ aus molilys erstem Posting gefolgt?

              Es hat mich einfach gereizt, mal direkt die style-Definitionen zu bearbeiten. In SELFHTML wird das Kapitel anscheinend ausgespart. Zu document.styleSheets konnte Google mir aber weiterhelfen.

              Natürlich habe ich molilys „bessere Lösung“ nicht vergessen, werde sie auch für Tabellen mit nur wenigen Spalten einsetzen. In der Kürze liegt die Würze.

              Gruß, Don P

    2. Mahlzeit,

      Eine bessere Lösung wäre es, einfach die Klasse der Tabelle zu ändern. Durch entsprechende Style-Regeln wird dann die jeweilige Spalte umformatiert:

      .spalte1aktiv .spalte1, .spalte2aktiv .spalte2, .spalte3aktiv .spalte3, ... { font-weight:bold; }

      Eine noch bessere (*g*) Lösung wäre es, einfach die Klassen "spalte1", "spalte2" usw. beizubehalten und nur der aktiven Spalte zusätzlich die Klasse "aktiv" zuzuweisen (oder eben wieder zu entfernen) - schließlich kann ein Element auch zu <http://de.selfhtml.org/css/formate/zentrale.htm#klassen@title=mehreren Klassen> gehören.

      Das Problem ist nur, dass diese Auflistung lang werden kann, je nachdem, wieviel Spalten du hast.

      Dann hat man dieses Problem nicht mehr in dem Maße.

      MfG,
      EKKi

      --
      sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
      1. Hallo,

        nur der aktiven Spalte zusätzlich die Klasse "aktiv" zuzuweisen (oder eben wieder zu entfernen)

        Das ist das »Abklappern jeder einzelnen Zelle der umzuformatierenden Spalten«, das ist als umständlichste Lösung bezeichnet hatte. ;)

        Dann braucht man eine JavaScript-Logik, die alle n-ten td-Elemente in jedem tr anspricht. Und eine Logik, die allen Elemente der vorher aktiven Spalte die Klasse wieder wegnimmt. Das ist natürlich möglich, aber »Spalte« existiert nicht als Elementstruktur, daher ist es mit reinen DOM-Methoden Gefummel.

        schließlich kann ein Element auch zu <http://de.selfhtml.org/css/formate/zentrale.htm#klassen@title=mehreren Klassen> gehören.

        Das ist dann ohnehin unnötig.

        Mathias

        1. Mahlzeit,

          Das ist das »Abklappern jeder einzelnen Zelle der umzuformatierenden Spalten«, das ist als umständlichste Lösung bezeichnet hatte. ;)

          Oooch, dafür gibt's doch Helfer:
          .getElementsByClassName(foo)
          .toggleClassName(foo)

          :-)

          MfG,
          EKKi

          --
          sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
          1. Hallo,

            Das ist das »Abklappern jeder einzelnen Zelle der umzuformatierenden Spalten«, die ich als umständlichste Lösung bezeichnet hatte. ;)

            Genau. Eben das wollte ich vermeiden. Es geht um wirklich lange Tabellen mit tausenden von Zeilen.

            Oooch, dafür gibt's doch Helfer:
            .getElementsByClassName(foo)
            .toggleClassName(foo)

            Eine getElementsByClassName bemühe ich bereits um nach Spalten zu sortieren, will die Funktion aber nicht überstrapazieren, sonst wird sie mir noch müde, oder ich, beim warten auf das Ergebnis...

            Auch sonst ging's bis jetzt ohne Framework.

            Gruß, Don P

          2. Hallo,

            Oooch, dafür gibt's doch Helfer

            Ja, das ist hinsichtlich der Kosten/Nutzen-Verhältnis und Performance aufgebläht und »umständlich«.

            Mathias

  2. Hallo Don,

    Es gelingt mir nicht, die style-Definition für alle Elemente mit class="spalte1" von bold auf normal umzustellen und dafür die Elemente der sortierten Spalte z.B. mit class="spalte3" fett zu formatieren.

    Muss es unbedingt die Schriftstärke sein, die die indizierende Spalte anzeigt? Wenn nein, dann hätte ich einen anderen, um die Ecke gedachten Lösungsansatz.

    Tabellen lassen sich nun ja eher schlecht im Baum-Modell von HTML unterbringen und noch schlechter mit dem Baummodell von CSS formatieren. Dennoch gibt es für Spalten minimale Formatierungsmöglichkeiten im Tabellenmodell von CSS 2(.1). Es gehen nicht alle CSS-Eigenschaften, denn schließlich liegen die virtuellen Spalten im z-Index unter den Tabellenreihen- und zellen und vor allem dem Inhalt, sind also praktisch seperate Boxen, die man formatiert. Und selbst die empfohlenen Eigenschaften sind meiner Erfahrung nach in den Browsern verbuggt umgesetzt; besonders wenn man sie dynamisch ändern will. Die Hintergrund-Eigenschaften gehen noch am besten, natürlich immer vorausgesetzt, die davor liegenden Zeilen und Zellen und Boxen sind transparent.

    Damit hat man dann eine Möglichkeit nur durch Ändern der Klasse oder ID eine Tabellenspalte schnell einen neuen Hintergrund zu verpassen. Ich hab da mal ein simples Beispiel vorbereitet, es allerdings nur in Safari und Firefox getestet.

    Vielleicht wäre das ein Ansatz?

    Tim

    1. Hallo Tim,

      Muss es unbedingt die Schriftstärke sein, die die indizierende Spalte anzeigt?

      Eigentlich ja, denn meine Tabellen haben schon drei verschiedene Farben a) in der Kopfzeile, b) als Hintergrund der Zeilen und c) als hervorgehobene Zeilenfarbe, wenn man man mit der Maus darauf zeigt. Wenn ich dann noch  weitere Farbe für Spaltenhervorhebung einsetze, wird das vielleicht etwas zu bunt. Werde mal ein bisschen experimentieren.

      Wenn nein, dann hätte ich einen anderen, um die Ecke gedachten Lösungsansatz.

      Warum um die Ecke? Das ist doch genau das, was man erwartet: Durch eine einzige Zuweisung die Darstellung einer ganzen Spalte ändern – genial. Und sogar ohne dass die body-Zellen einen className haben müssen.
      Vielen Dank für die Anregung und die Links. Das ist mir alles ganz neu.

      Ich hab da mal ein simples Beispiel vorbereitet, es allerdings nur in Safari und Firefox getestet.

      Es funktioniert auch in Opera 9.26, aber leider nicht im IE6* und auch nicht in den älteren Mozillas 1.3 und 1.6, im Unterschied zu meiner Lösung (ändern der CSS-Eigenchaft), die in allen von mir getesteten Browsern funktioniert: IE, Opera, Mozilla 1.3ff.

      * IE7 will sich bei mir nicht installieren lassen. Es wäre aber sehr interessant zu erfahren, ob der das unterstützt oder nicht. Wenn nicht, sehe vorerst schwarz für diese Technologie.

      Gruß, Don P