Zorro: Objekt in Style-Property "verwandeln"?

Hallo,

ich suche den eierproduzierenden Synthesefaserlaktosepaarhufer - ...und zwar eine Funktion, mit der ich sämtliche Style Properties addressieren und ändern kann, in die Richtung:

function ChangeStyle(Element, Change, Wert) {
	document.getElementById(Element).style.Change = Wert;
}
ChangeStyle("BeispielSection", top, "300px");

Problem ist hier natürlich top, das als Objekt statt als Style-Property übergeben wird, und daher [nicht wie erwünscht] Change setzt.

...daher meine Frage: wie krieg ich das hin?

Danke für eure Bemühungen,

Zorro.

  1. Hallo Zorro,

    ich suche den eierproduzierenden Synthesefaserlaktosepaarhufer - ...und zwar eine Funktion, mit der ich sämtliche Style Properties addressieren und ändern kann, in die Richtung:

    function ChangeStyle(Element, Change, Wert) {
    	document.getElementById(Element).style.Change = Wert;
    }
    ChangeStyle("BeispielSection", top, "300px");
    

    Problem ist hier natürlich top, das als Objekt statt als Style-Property übergeben wird, und daher [nicht wie erwünscht] Change setzt.

    Es ist im allgemeinen keine gute Idee, massenhaft inline-styles zu setzen. Am besten löst man sowas, indem man (ggf. per JS) eine Klasse setzt und die gewünschten CSS-Angaben für diese Klasse festlegt. Beachte die Trennung der Zuständigkeiten.

    Bis demnächst
    Matthias

    --
    Du kannst das Projekt SELFHTML unterstützen,
    indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
  2. Mahlzeit,

    ich suche den eierproduzierenden Synthesefaserlaktosepaarhufer

    wenn du ihn gefunden hast, sag Bescheid! :-)

    ...und zwar eine Funktion, mit der ich sämtliche Style Properties addressieren und ändern kann, in die Richtung:

    function ChangeStyle(Element, Change, Wert) {
    	document.getElementById(Element).style.Change = Wert;
    }
    ChangeStyle("BeispielSection", top, "300px");
    

    Problem ist hier natürlich top, das als Objekt statt als Style-Property übergeben wird, und daher [nicht wie erwünscht] Change setzt.

    ...daher meine Frage: wie krieg ich das hin?

    In Javascript sind Arrays und Objekte (fast) dasselbe. Das kannst du ausnutzen: foo.bar kannst du auch als foo["bar"] ansprechen.

    Live long and pros healthy,
     Martin

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

      In Javascript sind Arrays und Objekte (fast) dasselbe. Das kannst du ausnutzen: foo.bar kannst du auch als foo["bar"] ansprechen.

      also so:

      function ChangeStyle(id, property, value) {
        document.getElementById(id).style[property] = value;
      }
      ChangeStyle("BeispielSection", "top", "300px");
      

      Es stellt sich nun die Frage, warum man diesen Einzeiler in eine Funktion verpacken muss. Der Aufruf derselben ist kaum weniger aufwendig als ihr Inhalt:

      document.getElementById("BeispielSection").style["top"] = "300px";
      

      Liebe Grüße

      Felix Riesterer

  3. Hallo Zorro,

    als grundsätzliche Überlegung möchte ich Dir mitgeben, dass man styles möglichst nur dann von Hand setzen sollte, wenn es nicht anders geht. Zum Beispiel, wenn die Werte berechnet werden müssen. Im Normalfall sollte man seine Seite über fertige CSS Regeln stylen, und wenn man etwas umstylen will, Klassen verwenden. Du kannst über die classList Eigenschaft einem Element jederzeit Klassen hinzufügen und wegnehmen. classList wird nicht vom Internet Explorer unterstützt, aber auf MDN gibt's einen umfangreichen Polyfill dafür. Ohne den Polyfill musst Du Dir eine Hilfsfunktion bauen, um das className Attribut zu manipulieren.

    Zu deiner Frage.

    So, wie Du top übergibst, ist es eine Variable. Was steht da denn drin?

    Der Zugriff auf ein Property, das nur namentlich bekannt ist, erfolgt nicht über den Punkt-Operator, sondern über die von Arrays bekannte Indexschreibweise.

    Du solltest ChangeStyle auch nicht so gestalten, dass Du eine Element-ID übergibst. Damit schränkst Du die Wiederverwendbarkeit von ChangeStyle unnötig ein. Entweder übergibst Du einen CSS Selektor und suchst das Element mit document.querySelector (oder querySelectorAll), oder du suchst das Element vor dem Aufruf und übergibst das DOM Objekt des Elements.

    D.h. du könntest ChangeStyle so aufrufen:

    let element = document.getElementById("BeispielSection");
    ChangeStyle(element, "top", "300px");
    

    oder so:

    ChangeStyle(document.getElementById("BeispielSection"), "top", "300px");
    

    und solltest dann in ChangeStyle so vorgehen:

    function ChangeStyle(Element, Change, Wert) {
    	Element.style[Change] = Wert;
    }
    

    Wenn Du eine Variable top hast, in der sich der String "top" befindet, kannst Du natürlich auch diese Variable als Parameter übergeben.

    Wenn Du mit CSS Selektoren arbeiten möchtest, könnte man es so machen:

    //           ID Selektor
    ChangeStyle("#BeispielSection", "top", "300px");
    
    function ChangeStyle(selector, Change, Wert) {
       let elems = document.querySelectorAll(selector);
       for (let i=0; i<elems.length; i++)
          elems[i].style[Change] = Wert;
       }
    }
    

    querySelectorAll wird hinreichend unterstützt (ab IE 8), dafür brauchst Du keinen Polyfill mehr. Statt eines ID Selektors könntest Du auch andere Selektoren übergeben und so mehrere Elemente auf einmal stylen. Ich habe bewusst die for(;;) Scheife verwendet und nicht das .forEach Konstrukt, um hier nicht auf forEach Polyfills für den Internet Explorer eingehen zu müssen.

    Ich finde allerdings den Nutzen dieser Funktion noch begrenzt.

    Du schriebst, du würdest top als "Objekt" übergeben. Das ist eigentlich ein guter Ansatz, ein Objekt kann mehrere Eigenschaften haben und erlaubt Dir das setzen mehrerer Style-Eigenschaften auf einmal.

    let newStyles = {
       top: "300px",
       left: "50px",
       margin: "100px 75px"
    };
    

    Dann muss ChangeStyle aber etwas anders aussehen: Es muss eine Schleife über die Eigenschaften dieses Objekts laufen lassen. Das geht mit der for...in Schleife oder mit Object.getOwnPropertyNames. Unterschied ist, ob Du geerbte Properties mitnehmen möchtest (das tut for...in) oder nicht.

    Mit for...in sieht es so aus:

    function ChangeStyle(selector, newStyle) {
       let elems = document.querySelectorAll(selector);
       for (let i=0; i<elems.length; i++) {
          for (let n in newStyle) {
             elems[i].style[n] = newStyle[n];      
          }
       }
    }
    

    Wenn Du keine geerbten Properties verwenden willst, brauchst Du Object.getOwnPropertyNames(newStyle). Diese Methode liefert ein Array mit Property-Namen, das musst Du mit einer for(;;) Schleife verarbeiten (funktioniert auch im Internet Explorer) oder mit der for...of Schleife (funktioniert nicht im Internet Explorer). Das sei dann als einfache Übung dem Leser überlassen 😉

    Rolf

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

      man kann auch Object.assign verwenden, um die eigenen Eigenschaften eines Objekts zu kopieren.

      const changeStyles = (element, newStyles) => {
          Object.assign(element.style, newStyles);
      };
      
      changeStyles(document.getElementById('myElement'), {
         top: "300px",
         left: "50px",
         margin: "100px 75px"
      });
      

      Viele Grüße

      1. Hallo Vampirschatten,

        danke, damit hab ich wieder mal was gelernt. Die Methode kannte ich gar nicht.

        Der IE kennt sie aber nicht, d.h. man braucht auch hier einen Polyfill in der Hinterhand.

        Rolf

        --
        sumpsi - posui - obstruxi
  4. Wow, danke für so viel Rückenwind!

    ...auch sehr viel gute verwertbare Info dabei, aber auch wenn ich die Styles ausschließlich CSS umhänge, ändert das ja wenig an der Endlösung -

    -statt

    (...).style[property] = value
    

    sieht ja

    (...).classList[add/remove/toggle](voll_stylische_Klasse)
    

    auch ganz frisch aus 😎