Olga: CSS-Eigenschaft @media mit Javascript angeben

Hallo,

ich habe folgendes Problem, an dem ich heute schon etwas länger sitze und keine Lösung finde:
Ich möchte mit Javascript eine CSS-Eigenschaft angeben, die aber nicht beim Drucken sichtbar sein soll. In CSS geht das ja mit "@media screen { ... }", aber wie geht das von Javascript aus? Ich hätte gerne, dass "document.all.textbox.style.width=myWidth-300;" nicht beim Drucken gilt.

Die einzige Lösung, die mir einfiel, was es, in zwischen "<HEAD>" und "</HEAD>" CSS-Code ("<style> ... </style>") mittels Javascript einzufügen, aber wie das geht, weiß ich leider auch nicht...

Kann mir jemand helfen?

Danke!

Olga

  1. Hallo,

    Deine Methode ist im Grunde die einfachste, aber ich erläutere erst mal, was sonst noch möglich wäre:

    Man kann so vorgehen, dass man per JavaScript eine neue Style-Regel in ein vorhandenes Screen-Stylesheet einfügt. Über document.styleSheets hat man JavaScript-Zugriff auf die Stylesheets eines Dokuments. Darüber kann man eine neue Style-Regel einfügen (z.B. #textbox { width:100px; }).

    Der Standard dazu ist DOM 2 Style, der allerdings meines Wissens nur von Gecko und Konqueror hinreichend umgesetzt wird. Opera kann dies gar nicht, MSIE kann es immerhin über einen kleinen Umweg. Ein Beispiel:

    <style type="text/css" media="screen"></style>  
    <script type="text/javascript">  
    [code lang=javascript]function addScreenRule (selector, declarations) {  
     // Kennt der Browser document.styleSheets und existiert bereits eines?  
     if (!document.styleSheets || document.styleSheets.length == 0) {  
      return false;  
     }  
     // Speichere das Stylesheet-Objekt zwischen  
     var stylesheet = document.styleSheets[0];  
     alert("use styleSheets[0]");  
     // insertRule ist der standardisierte Weg (Gecko, Konqueror)  
     if (stylesheet.insertRule) {  
      new_rule_number = stylesheet.insertRule(selector + " { " + declarations + " }",  
       stylesheet.cssRules.length);  
      // Nur eine Überprüfung, ob die eingefügte Regel auch wieder über JavaScript ausgelesen werden kann  
      if (stylesheet.cssRules[new_rule_number].cssText.length > 0) {  
       alert("added with stylesheet.insertRule");  
       return true;  
      }  
     } else if (stylesheet.addRule) {  
      // MSIE kennt addRule statt insertRule  
      stylesheet.addRule(selector, declarations);  
      alert("added with stylesheet.addRule");  
      return true;  
     }  
     // keine Methode war erfolgreich  
     return false;  
    }  
      
    window.onload = function () {  
     // Beim abgeschlossenen Laden der Seite aufrufen:  
     var result = addScreenRule("#p", "font-weight:bold;");  
     if (!result) {  
      alert("Fehler beim Setzen");  
     }  
    };
    

    </script>
    <p id="p">bla</p>[/code]

    Es existiert also ein Screen-Stylesheet, das erste im Dokument (document.styleSheets[0]). Dies kann auch ein leeres style-Element sein, Hauptsache, es ist ausdrücklich für media="screen". Die Funktion addScreenRule() bekommt als Parameter den Selektor (z.B. #p) und die Deklarationen (eigenschaft:wert; eigenschaft:wert; ...). Über insertRule() bzw. addRule() werden dem Screen-Stylesheet dann die neue Regel hinzugefügt.

    Da dies wie gesagt z.B. nicht im Opera funktioniert, muss man die Funktion sowieso um eine weitere Alternativmethode erweitern, die hast du schon angesprochen:

    Die einzige Lösung, die mir einfiel, was es, in zwischen "<HEAD>" und "</HEAD>" CSS-Code ("<style> ... </style>") mittels Javascript einzufügen, aber wie das geht, weiß ich leider auch nicht...

    Elemente erzeugst du einfach per document.createElement(). Attribute (z.B. type und media) setzt du direkt als Objekteigenschaften an diesem erzeugten Element. Den Inhalt des style-Elements erzeugst du mit document.createTextNode(). Den Textknoten hängst du an den Elementknoten und den Elementknoten schließlich an das head-Element im Dokument. Schematisch:

    function addScreenRule (rule) {  
     // Element erzeugen  
     var style_element = document.createElement("style");  
     // Attribute setzen  
     style_element.media = "screen";  
     style_element.type = "text/css";  
     // Textknoten erzeugen mit dem übergebenen String  
     var textknoten = document.createTextNode(rule);  
     // Hänge Textknoten an das Style-Element  
     style_element.appendChild(textknoten);  
     // Hänge Style-Element an den Head  
     document.getElementsByTagName("head")[0].appendChild(style_element);  
    }  
    var breite = myWidth - 300;  
    addScreenRule("#textbox { width:" + breite + "px; }");
    

    Mein Beispielscript im Thread style-Element erzeugen per Script vereinigt alle Methoden. Dieses Script hängt entweder neue Regeln an ein vorhandenes Stylesheet an (mit der oben beschriebenen Methode). Wenn keines vorhanden ist, dann wird eines erzeugt, entweder über DOM 2 Style oder, wenn der Browser dies nicht unterstützt, auf die einfache Methode mit dem Erzeugen und Einfügen eines style-Elements. (Dort bin ich aber nicht auf Formatierungen für einen Medientyp eingegangen.)

    Das nur zur Information – wenn du es dir nicht kompliziert machen willst, dann reicht wie gesagt die Methode aus, auf die du schon selbst gekommen warst. Die funktioniert nämlich in den meisten Browsern ohne Umwege und hat auch keine besonderen Nachteile.

    Mathias

    1. // Hänge Textknoten an das Style-Element
      style_element.appendChild(textknoten);

        
      
      > Das nur zur Information – wenn du es dir nicht kompliziert machen willst, dann reicht wie gesagt die Methode aus, auf die du schon selbst gekommen warst. Die funktioniert nämlich in den meisten Browsern ohne Umwege und hat auch keine besonderen Nachteile.  
        
      Naja, da habe ich den [verlinkten Thread](http://forum.de.selfhtml.org/archiv/2005/7/t112056/#m707145) vergessen: MSIE erlaubt das Anfügen von Textknoten an style-Elemente nicht. Also ist die addRule-Lösung im MSIE wohl notwendig.  
        
      Eine noch einfachere Möglichkeit wäre das Überschreiben des Inhalts des existierenden style-Element über [innerHTML](http://de.selfhtml.org/javascript/objekte/all.htm#inner_html). Da bekomme ich in meinem IE aber eine seltsame Fehlermeldung...  
        
      Mathias
      
      1. hi,

        Eine noch einfachere Möglichkeit wäre das Überschreiben des Inhalts des existierenden style-Element über innerHTML. Da bekomme ich in meinem IE aber eine seltsame Fehlermeldung...

        So seltsam ist die nicht - schließlich beschreibt die MSDN für die innerHTML Property ausdrücklich, dass innerHTML u.a. für style im IE read-only implementiert ist.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. Hallo,

          So seltsam ist die nicht - schließlich beschreibt die MSDN für die innerHTML Property ausdrücklich, dass innerHTML u.a. für style im IE read-only implementiert ist.

          Ah, danke, das hatte ich befürchtet. Mit »seltsam« meinte ich, dass die Fehlermeldung wenig aussagekräftig »Unknown runtime error« lautete, was aber auch an der Linux-Emulation liegen kann.
          innerHTML von head ist übrigens auch nicht definiert, da wusste das Forumsarchiv auch keine andere Möglichkeit als addRule().

          Mathias

          1. hi,

            Mit »seltsam« meinte ich, dass die Fehlermeldung wenig aussagekräftig »Unknown runtime error« lautete,

            OK, du hast recht, »seltsam« ist sie schon - aber wie gesagt, schnell logisch erklärt.
            Dass die Aussagekraft der Meldungen des IE oftmals zu wünschen übrig lässt, steht auf einem anderen Blatt - ein "Property is readonly" o.ä. wäre hier sicher wünschenswerter gewesen.

            was aber auch an der Linux-Emulation liegen kann.

            Nein, ich glaube nicht - IIRC ist es unter Windows das gleiche.
            Da scheint man beim Error Handling einfach ein bisschen unsauber vorgegangen zu sein.

            gruß,
            wahsaga

            --
            /voodoo.css:
            #GeorgeWBush { position:absolute; bottom:-6ft; }
            1. Hallo,

              vielen Dank für die zahlreichen und hilfreichen Antworten! Ich habe das ganze gerade ausprobiert (die 1. vorgeschlagene Lösung mit AddScreenRule) - im IE klappt's wunderbar, aber im Firefox geht's leider nicht... Es gibt keine Fehlermeldung, aber es wird auch keine Breite festgesetzt.

              Kann mir da noch jemand helfen?

              Viele Grüße,
              Olga

              1. Hallo,

                danke, hat sich erledigt, geht nun auch in Firefox :)

                Danke nochmal!

                Olga