muderseb: Klassen selektieren in JavaScript

Hallo zusammen,

mal eine Anfängerfrage zu JavaScript: Wenn ich bestimmte HTML-Elemente mittels des "style"-Objekts bzgl. ihrer CSS-Eigenschaften ändern will, diese Elemente aber nach dem Class-Attribut selektieren möchte (also will ich beispielsweise nicht die CSS-Angaben von allen "p"-Objekten ändern, sondern nur von solchen, die das Attribut class="beispiel" aufweisen).

Im JavaScript-Abschnitt von SELFHTML habe ich hierzu nichts gefunden. Zum Ändern von CSS-Angaben wird hier wenn ich richtig gelesen habe einfach empfohlen, entweder "GetElementsByTagName", "GetElementsById" oder "GetElementsByName" zusammen mit dem style-Objekt zu verwenden. Das gibt mir aber doch noch keine Möglichkeit an die Hand, nur Elemente einer bestimmten Klasse zu ändern, oder?

Und noch ein kleines Problem: Bisher habe ich folgendes Musterbeispiel aus SELFHTML verwendet, um CSS dynamisch zu ändern:

<script type="text/javascript">
function setCSS () {
  for (var i = 0; i < document.getElementsByTagName("p").length; i++) {
    document.getElementsByTagName("p")[i].style.border = "solid red 10px";
    document.getElementsByTagName("p")[i].style.backgroundColor = "#FF9933";
    document.getElementsByTagName("p")[i].style.color = "#FFFFFF";
    document.getElementsByTagName("p")[i].style.fontSize = "250%";

Die Funktion kapiere ich auch so weit, und es funktioniert auch mit fast allen Elmenten. Will ich jetzt aber beispielsweise keine Absätze, sondern Bilder neu formatieren und schreibe etwa:

<script type="text/javascript">
function setCSS () {
  for (var i = 0; i < document.getElementsByTagName("img").length; i++) {
    document.getElementsByTagName("img")[i].style.border = "solid red 1px";

dann werden ALLE HTML-Elemente auf dem Bildschirm mit einem derart spezifizierten Rahmen ausgestattet. Warum??

Danke im voraus für eure Hilfe,
Sebastian

  1. <script type="text/javascript">
    function setCSS () {
      for (var i = 0; i < document.getElementsByTagName("img").length; i++) {
        document.getElementsByTagName("img")[i].style.border = "solid red 1px";

    dann werden ALLE HTML-Elemente auf dem Bildschirm mit einem derart spezifizierten Rahmen ausgestattet. Warum??

    Nein das ist nicht so ist.

    Struppi.

  2. Hallo,

    also will ich beispielsweise nicht die CSS-Angaben von allen "p"-Objekten ändern, sondern nur von solchen, die das Attribut class="beispiel" aufweisen

    Such mal nach getElementsByClassName - das ist eine Helferfunktion, die die fraglichen Elemente durchgeht und einfach über className prüft, ob sie in Frage kommen.

    Zum Ändern von CSS-Angaben wird hier wenn ich richtig gelesen habe einfach empfohlen, entweder "GetElementsByTagName", "GetElementsById" oder "GetElementsByName" zusammen mit dem style-Objekt zu verwenden. Das gibt mir aber doch noch keine Möglichkeit an die Hand, nur Elemente einer bestimmten Klasse zu ändern, oder?

    Für sich genommen nicht, du kannst aber beim Durchlaufen des Rückgabewerts wie gesagt filtern.

    for (var i = 0; i < document.getElementsByTagName("p").length; i++) {
        document.getElementsByTagName("p")[i].style.border = "solid red 10px";
        document.getElementsByTagName("p")[i].style.backgroundColor = "#FF9933";
        document.getElementsByTagName("p")[i].style.color = "#FFFFFF";
        document.getElementsByTagName("p")[i].style.fontSize = "250%";

    Kleiner Hinweis zur Performance: Das sollte man so nicht notieren, weil es sehr langsam läuft, da document.getElementsByTagName("p") immer wieder aufgerufen wird und .length ständig abgefragt wird, was unnötig ist. Besser wäre wohl:

    for (
      var i = 0, list = document.getElementsByTagName("p"), element;
      element = list[i];
      i++
    ) {
       element.style.border = "1px solid red";
       usw.
    }

    for (var i = 0; i < document.getElementsByTagName("img").length; i++) {
        document.getElementsByTagName("img")[i].style.border = "solid red 1px";

    dann werden ALLE HTML-Elemente auf dem Bildschirm mit einem derart spezifizierten Rahmen ausgestattet.

    Das kann nicht sein.

    Mathias

    1. Hallo Mathias,

      Besser wäre wohl:

      for (

      var i = 0, list = document.getElementsByTagName("p"), element;
        element = list[i];
        i++
      ) {
         element.style.border = "1px solid red";
         //usw.
      }

      Was ist das für eine seltsame Syntax für die for-Schleife? Dei ist in SELFHTML anscheinend nirgends beschrieben. Zwar habe ich schon davon gelesen, dass man den Komma-Separator im Initialisations-Teil der for-Schleife benutzen kann, konkret ist mir das aber noch nirgends vorgekommen.  
        
      Es werden offenbar die drei Variablen i, list und element deklariert, soweit so gut. Aber im Bedingungs-Teil steht kein üblicher Vergleich mit Vergleichsoperatoren, sondern eine Zuweisung element = list[i];  
        
      Gibt eine Zuweisung denn auch einen Wert zurück wie ein Vergleich, also etwa false, falls list[i] nicht existiert?  
        
      Danke, Don P
      
      1. Was ist das für eine seltsame Syntax für die for-Schleife? Dei ist in SELFHTML anscheinend nirgends beschrieben. Zwar habe ich schon davon gelesen, dass man den Komma-Separator im Initialisations-Teil der for-Schleife benutzen kann, konkret ist mir das aber noch nirgends vorgekommen.

        Naja, die for-Schleife hat drei Parameter die nichts anderes bedeuten wie:

        for( tu_was_vor_der_schleife(); tu_was_in_der_schleife_solange_es_wahr_ist(); tu_was_am_ende_der_schleife() );  
        
        

        Struppi.

        1. Naja, die for-Schleife hat drei Parameter die nichts anderes bedeuten wie:

          for( tu_was_vor_der_schleife(); tu_was_in_der_schleife_solange_es_wahr_ist(); tu_was_am_ende_der_schleife() );

            
          Das schon, aber kann denn eine normale Zuweisung wie  
          element = list[i];  
          wahr oder falsche sein? Das ist es, was mich bei deinem Code wundert.  
            
          Don P
          
          1. Das schon, aber kann denn eine normale Zuweisung wie
            element = list[i];
            wahr oder falsche sein? Das ist es, was mich bei deinem Code wundert.

            Wenn du so fragst, mich auch, eine Zuweisung ist immer wahr.

            Struppi.

            1. Hi,

              Wenn du so fragst, mich auch, eine Zuweisung ist immer wahr.

              Eine Zuweisung hat als Wert den zugewiesenen Wert und NICHT wahr.

              cu,
              Andreas

              --
              Warum nennt sich Andreas hier MudGuard?
              O o ostern ...
              Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
              1. Hi,

                Eine Zuweisung hat als Wert den zugewiesenen Wert und NICHT wahr.

                Aha, wenn das so ist, dann funktioniert

                for (

                var i = 0, list = document.getElementsByTagName("p"), element;
                  element = list[i];
                  i++
                ) {...}
                tatsächlich genial. Denn wenn list[i] 'undefined' wird, ist das der zugewiesene Wert, und die ganze Zuweisung element = list[i]; evaluiert zu false, was die Schleife beendet. Cool!

                Bleibt noch zu prüfen, ob so ein Elementknoten nicht auch sonst mal irgendwie "falsy" werden könnte.

                Don P

                1. Hallo miteinander,

                  danke für eure Hilfe, insbesondere der Link zu dem Script, mit dem man Klassen evaluieren kann hat super geholfen!!!

                  Beste Grüße,
                  Sebastian

                2. Hallo,

                  Denn wenn list[i] 'undefined' wird, ist das der zugewiesene Wert, und die ganze Zuweisung element = list[i]; evaluiert zu false, was die Schleife beendet. Cool!

                  list wird null, weil in DOM Core definiert ist, dass NodeList.item(index) null zurückgibt, wenn kein solches Item existiert. Das geht aber auch nur mit NodeLists bzw. Arrays, die keine Elemente enthalten können, die bei einer Umwandlung in Boolean false ergeben.

                  Bleibt noch zu prüfen, ob so ein Elementknoten nicht auch sonst mal irgendwie "falsy" werden könnte.

                  Nö, das ist nicht möglich.

                  Mathias

  3. Hello out there!

    Das gibt mir aber doch noch keine Möglichkeit an die Hand, nur Elemente einer bestimmten Klasse zu ändern, oder?

    Wesentlich einfacher, als den CSS-Regeln für eine Klasse zu ändern, ist es, die Klassenzugehörigkeit eines Elements zu ändern. 'body' bietet sich an; die dynamisch zu formatierenden Elemente der Klasse 'foo' selektierst du mit dem Nachfahrenselektor:

    .stil1 .foo { /* Deklarationen für Stil 1 */ }  
    .stil2 .foo { /* Deklarationen für Stil 2 */ }
    

    Das einzige, was JavaScript tut, ist die Umschaltung

    document.body.className = "stil1"; //bzw. "stil2"

    [</archiv/2007/9/t159017/#m1035383>]

    See ya up the road,
    Gunnar

    --
    „Und [dieses Forum] soll […] auch ein Fachforum bleiben und kein Psychologieforum werden.“ (Kirsten Evers)