Tobias Müller: DOM: createElement(), appendChild() und die lieben Browser

Hallo Ihr,

Ich will mit JS ein externes Stylesheet in den Head einer XHTML-Datei schreiben. Alles kein Problem, wenn ich document.writeln() verwende machen alle Browser mit.

Nun habe ich mir gedacht, das kann man sicher auch alternativ lösen. Warum ich Alternativen suche? Weil Mozillas XML-Parser write() und writeln() nicht kennt bzw. ignoriert. Man könnte zwar jetzt sagen, es sei verschwendete Zeit, deshalb Alternativen zu suchen, da ich eh nicht vorhabe, das Dokument als .xml oder .xhtml abzuspeichern, aber meine Neugier ist nun halt geweckt.

Nun habe ich zwei Alternativen versucht:

1. Alternative:

<script type="text/javascript">
/* <![CDATA[ */
var styleEl = document.createElement('style');
var styleInhalt = document.createTextNode('@import url("styles/adepto.css");');
styleEl.setAttribute('type', 'text/css');
styleEl.appendChild(styleInhalt);
document.getElementsByTagName('head')[0].appendChild(styleEl);
/* ]]> */
</script>

Ich lasse also ein neues Style-Element erstellen und füge dem als Textknoten '@import url("styles/adepto.css");' hinzu. Das Ergebnis im Test ist relativ verheerend. IE 6 spuckt einen Fehler aus ("unerwarter Aufruf oder Zugriff" in der vorletzten Zeile des Scripts), Opera 6 macht gar nichts, Netscape 6.0 und 6.2 ebenso. Die einzigen Browser, in denen es funktioniert, sind Netscape 7, Firefox und Opera 7.
Warum der IE und Netscape 6 sich verweigern ist mir absolut schleierhaft, können müssten sie es doch eigentlich? Oder habe ich was falsch gemacht?

Die 2. Alternative:

<script type="text/javascript">
/* <![CDATA[ */
var styleEl = document.createElement('link');
styleEl.setAttribute('rel', 'stylesheet');
styleEl.setAttribute('type', 'text/css');
styleEl.setAttribute('href', 'styles/adepto.css');
document.getElementsByTagName('head')[0].appendChild(styleEl);
/* ]]> */
</script>

Ich lasse als ein neues Link-Element erstellen und gebe diesem gleich die relevanten Attribute per setAttribute() mit. Hier sieht es schon ganz anders aus als oben. Der IE macht ab Version 4 (in der 4er Version mit document.all angesprochen) problemlos mit, ebenso Netscape ab Version 6.2.

Jetzt bleiben nur noch Netscape 6.0, der seltsamerweise immer noch nicht mitmacht, und Opera 6 übrig, die ich irgendwie aus der Reserve locken will. Aber wie? Ich bin mit meinem Latein am Ende! Habt ihr noch Ideen bzw. andere Alternativen auf Lager?

Ich würde mich über Antworten freuen, auch wenn dieses Problem eher theoretischer Natur ist.

MfG Mülli

--
Viva Colonia!
  1. Hallo!

    1. Alternative:

    Du kannst nicht einfach so im Stylebereich ein paar CSS-Angaben als textknoten hinzufügen, so wie Du es vor hast. Du mußt da mit speziellen Methoden arbeiten.

    Mozilla:
    http://www.mozilla.org/docs/dom/domref/dom_style_ref3.html
    bzw:
    http://www.mozilla.org/docs/dom/domref/dom_style_ref14.html
    http://www.mozilla.org/docs/dom/domref/dom_el_ref48.html

    elm = document.styleSheets.length-1;
    document.styleSheets.item(elm).insertRule("@import url('style.css');", 0);

    IE:
    http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/addrule.asp

    Bei der @import-Anweisung schmiert der IE regelmäßig ab. Klassen etc. ist kein Problem.

    Die 2. Alternative:

    Jetzt bleiben nur noch Netscape 6.0, der seltsamerweise immer noch nicht mitmacht, und Opera 6 übrig, die ich irgendwie aus der Reserve locken will. Aber wie? Ich bin mit meinem Latein am Ende! Habt ihr noch Ideen bzw. andere Alternativen auf Lager?

    Vergesse es! Opera 6 wirst Du wohl kaum dazu überreden können. Im Netscape 6.0 könnte es vielleicht gehen. Schaue mal beim Netscape 6 welchen Mozilla dahinter steckt. Dann besorgst Du Dir diesen Mozilla und installierst den DOM-Inspektor mit. Dann kanst Du ja schauen ob es im DOM-Baum, nach dem erstellen vorhanden ist.

    MfG, André Laugks

    --
    L-Andre @ gmx.de
    1. was vergessen bezüglich Opera:

      http://www.opera.com/docs/specs/js/

      zu Deinem Problem -> http://www.opera.com/docs/specs/js/dom/css/
      "no" soweit man schauen kann.

      MfG, André Laugks

      --
      L-Andre @ gmx.de
    2. Hallo André,

      Danke für deine Antworten!

      1. Alternative:

      Du kannst nicht einfach so im Stylebereich ein paar CSS-Angaben als textknoten hinzufügen, so wie Du es vor hast. Du mußt da mit speziellen Methoden arbeiten.

      Standardgemäß ist es aber schon, oder? Jedenfalls schliesse ich das daraus, dass die neueren Mozillas ja mitgemacht haben.

      IE:
      http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/addrule.asp

      Bei der @import-Anweisung schmiert der IE regelmäßig ab. Klassen etc. ist kein Problem.

      OK, ich glaube diesen Lösungsansatz schmeisse ich über Board.

      Die 2. Alternative:

      Vergesse es! Opera 6 wirst Du wohl kaum dazu überreden können. Im Netscape 6.0 könnte es vielleicht gehen. Schaue mal beim Netscape 6 welchen Mozilla dahinter steckt. Dann besorgst Du Dir diesen Mozilla und installierst den DOM-Inspektor mit. Dann kanst Du ja schauen ob es im DOM-Baum, nach dem erstellen vorhanden ist.

      Opera 6 wäre ja noch zu verschmerzen.
      Hinter Netscape 6.0 steckt Mozilla Milestone 18. Ich hab mir den jetzt mal runtergeladen und werde dann mal weitersehen.

      Gute Nacht allerseits. :)

      MfG Mülli

      --
      Viva Colonia!
      1. Hallo!

        Standardgemäß ist es aber schon, oder? Jedenfalls schliesse ich das daraus, dass die neueren Mozillas ja mitgemacht haben.

        Gute Frage! Keine Ahnung!

        Diese Methoden sind im DOM definiert.

        2. Document Object Model CSS
        http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/css.html
        insertRule: http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/css.html#CSS-CSSStyleSheet-insertRule

        Hinter Netscape 6.0 steckt Mozilla Milestone 18. Ich hab mir den jetzt mal runtergeladen und werde dann mal weitersehen.

        Im Netscape 6.0 war noch ein Mozilla Version<1 integriert.

        MfG, André Laugks

        --
        L-Andre @ gmx.de
        1. Hinter Netscape 6.0 steckt Mozilla Milestone 18. Ich hab mir den jetzt mal runtergeladen und werde dann mal weitersehen.

          Im Netscape 6.0 war noch ein Mozilla Version<1 integriert.

          Stimmt in Netscape7.0 ist die gleiche Geckoengine wie in Mozilla1.0.
          M18 ist eine sehr frühe Versione von Mozilla, erst danach begann man die Versionen mit 0.x zu bezeichnen.

          Um Netscape 6.0 braucht man sich aber wirklich keine Gedanken zu machen, den wird ja wohl kaum noch einer installiert haben.

          MfG
          Avalon

          1. Hallo,

            Stimmt in Netscape7.0 ist die gleiche Geckoengine wie in Mozilla1.0.
            M18 ist eine sehr frühe Versione von Mozilla, erst danach begann man die Versionen mit 0.x zu bezeichnen.

            Und diese M18 Version, die ich mir gezogen hab ist extrem buggy. Will man den Quelltext anzeigen, kommt erste eine leere weisse Seite, dann schmiert der Browser komplett ab. Der DOM-Inspector lässt sich zwar öffnen, weigert sich aber beharrlich etwas zu tun.

            Um Netscape 6.0 braucht man sich aber wirklich keine Gedanken zu machen, den wird ja wohl kaum noch einer installiert haben.

            Es geht mir auch weniger um die Notwenigkeit als meinen Ehrgeiz, das irgendwie hinzubekommen. Es besteht ja wie im Eröffnungspost beschrieben nicht mal wirklich die Notwendigkeit, das auf diese Weise zu lösen.

            Was mich vor allem irritiert ist die Tatasache, dass ich die Unterstützung der im Script verwendeten Methoden abfrage und Netscape 6.0 /Mozilla M18 dies bejahen und in das Script reingehen, dann aber nichts tun. Würden sie in den Else-Zweig mit document.writeln() springen, wär ich ja mittlerweile schon zufrieden.

            MfG Mülli

            --
            Viva Colonia!
            1. Hallo!

              Und diese M18 Version, die ich mir gezogen hab ist extrem buggy.

              Im 6.0 teste ich gar nicht, erst ab 6.2.

              Was mich vor allem irritiert ist die Tatasache, dass ich die Unterstützung der im Script verwendeten Methoden abfrage und Netscape 6.0 /Mozilla M18 dies bejahen und in das Script reingehen, dann aber nichts tun. Würden sie in den Else-Zweig mit document.writeln() springen, wär ich ja mittlerweile schon zufrieden.

              Mozilla M18 ist nun mal ein frühes Stadium. Da kann man die Unterstützung solcher Feature nicht erwarten.

              Vielleicht kann man dem das irgendwie beibringen. Du könntest mal bei
              Google-Groups suchen.

              Ich bin mir nicht wirklich sicher. Aber ich habe da so im Hinterkopf das man dem DOM-Baum "reloaden" mußte. Das kann ich jetzt aber auch mit etwas anderem verwechseln.

              MfG, André Laugks

              --
              L-Andre @ gmx.de
              1. Hallo,

                Im 6.0 teste ich gar nicht, erst ab 6.2.

                Hatte bis vor kurzem auch nur den 6.2, aber weil ich in der Akademie gar keinen 6er installiert hatte, hab ich mir dort mal den 6.0 installiert und dort ging dann auf einmal ein Scrollscript, das ich mir in mühevoller Arbeit erstellt hatte (und sogar mit der Krücke Opera 6 läuft), nicht. Das Problem war zwar in einer Minute gelöst, aber seitdem gehört er halt auch zu meinem Testparcours. ;)

                Vielleicht kann man dem das irgendwie beibringen. Du könntest mal bei
                Google-Groups suchen.

                Ich bin mir nicht wirklich sicher. Aber ich habe da so im Hinterkopf das man dem DOM-Baum "reloaden" mußte. Das kann ich jetzt aber auch mit etwas anderem verwechseln.

                Das klingt interessant. Ich werde mich mal umschauen.

                Öhm. Ich zitier mich nochmal aus einem Post von weiter oben:

                Kannst du mir gute deutschsprachige Literatur empfehlen, die weit in die Tiefen des DOM vordringt und gleichzeitig halbwegs idiotensicher ist? Ehrlich gesagt hab ich mich ja erst seit deinem HTML-Unterricht ausführlicher mit Javascript befasst, aber mit Selfhtml kommt man ja diesbezüglich nicht besonders weit wie ich finde.

                Gute Nacht. :-)

                MfG Mülli

                --
                Viva Colonia!
                1. Hallo!

                  Öhm. Ich zitier mich nochmal aus einem Post von weiter oben:

                  Kannst du mir gute deutschsprachige Literatur empfehlen, die weit in die Tiefen des DOM vordringt und gleichzeitig halbwegs idiotensicher ist? Ehrlich gesagt hab ich mich ja erst seit deinem HTML-Unterricht ausführlicher mit Javascript befasst, aber mit Selfhtml kommt man ja diesbezüglich nicht besonders weit wie ich finde.

                  Ohhh, habe ich nicht gelesen.

                  Mit diesem Buch hab eich JS gelernt.
                  JavaScript - Einführung, Programmierung und Referenz
                  http://www.dpunkt.de/buecher/3-89864-111-2.html
                  Hier gibt es sogar ein Probekapitel: Das Document Object Model

                  IMHO wohl mit eins der besten:
                  JavaScript - Das umfassende Referenzwerk
                  http://www.oreilly.de/catalog/jscript4ger/

                  Wenn Du das hier http://adepto.de/dateien/vscroll.html alles selbst gemacht hast, würde ich mir den Buchkauf überlegen.

                  MfG, André Laugks

                  --
                  L-Andre @ gmx.de
                  1. Hallo,

                    Mit diesem Buch hab eich JS gelernt.
                    JavaScript - Einführung, Programmierung und Referenz
                    http://www.dpunkt.de/buecher/3-89864-111-2.html
                    Hier gibt es sogar ein Probekapitel: Das Document Object Model

                    IMHO wohl mit eins der besten:
                    JavaScript - Das umfassende Referenzwerk
                    http://www.oreilly.de/catalog/jscript4ger/

                    Cool, danke! Ich denke eines davon werde ich mir besorgen. Ist eventuell eines der beiden speziell in Sachen DHTML besser?

                    Wenn Du das hier http://adepto.de/dateien/vscroll.html alles selbst gemacht hast, würde ich mir den Buchkauf überlegen.

                    Das habe ich schon komplett selber gemacht, war aber ne Heidenarbeit. Aber letztendlich (nachträglich betrachtet) ist das doch relativ primitiv, weil der Kern des Ganzen ja nichts anderes ist als eine Funktion, die style.top um x Pixel vergrößert oder verkleinert und sich immer wieder selbst aufruft. Nachdem ich dadrauf gekommen war, war es dann nur noch eine Sache des Denkens und Ausprobierens unter welchen Bedingungen was passieren darf und was nicht. Und so wurde dann aus einem kleinen Script mit fest vorgegeben Werten dieses Monstrum mit vielen Variablen. Aber ich musste halt immer wieder in Selfhtml nachschlagen, um überhaupt die Methoden kennenzulernen, wie man das umsetzt.

                    Naja, langer Rede kurzer Sinn, seitdem hat es mich jedenfalls gepackt und ein ausführliches Nachschlage- und Lernwerk ist bei mir sicherlich vonnöten. ;)

                    MfG Mülli

                    --
                    Viva Colonia!
                    1. Hallo!

                      Cool, danke! Ich denke eines davon werde ich mir besorgen. Ist eventuell eines der beiden speziell in Sachen DHTML besser?

                      Was ist DHTML? HTML und CSS mit JavaScript dynamisch zu ändern! Man benötigt also kein spezielles DHTML-Buch.

                      Das habe ich schon komplett selber gemacht, war aber ne Heidenarbeit.

                      Aber so lernt man es.

                      Aber letztendlich (nachträglich betrachtet) ist das doch relativ primitiv, weil der Kern des Ganzen ja nichts anderes ist als eine Funktion, die style.top um x Pixel vergrößert oder verkleinert und sich immer wieder selbst aufruft.

                      Und was soll da noch passieren?

                      So wie ich das sehe hast ja zwei Ebenen genommen. In der einen ist ein Loch und der Text in der anderen Ebene schaut durch. Die Ebene mit dem Text bewegst Du.

                      Ich hätte nur eine DIV genommen. Dieses DIV positioniert und ein Clipbereich (Ausschnitt des Text) definiert. Dann bewegt man das DIV und den Clipbereich in entgegengesetzer Richtung. dadurch entsteht der Scrolleffekt.

                      Naja, langer Rede kurzer Sinn, seitdem hat es mich jedenfalls gepackt und ein ausführliches Nachschlage- und Lernwerk ist bei mir sicherlich vonnöten. ;)

                      Ich habe das Buch (ältere Ausgabe) aus dem O'reilly-Verlag. Die Referenz nutze ich nicht wirklich.

                      Wenn Du aber ein kaufen möchtest hat das Buch aus dem O'reilly-Verlag die bessere Referenz. Ich weiss nicht wie die Referenz jetzt im Buch von Stefan Koch in der 3. Auflage ist.

                      MfG, André Laugks

                      --
                      L-Andre @ gmx.de
                      1. Hallo,

                        Was ist DHTML? HTML und CSS mit JavaScript dynamisch zu ändern! Man benötigt also kein spezielles DHTML-Buch.

                        Ich meinte das in Bezug auf gute nachvollziehbare Beispiele oder ähnliches.

                        Und was soll da noch passieren?

                        Gar nichts. Das Ding funktioniert in allen Browsern, die ich bedienen möchte einwandfrei. Ich wollte nur ausdrücken, dass das in Bezug auf das, was man mit JS so anstellen kann noch relativ primitiv ist.

                        Ich hätte nur eine DIV genommen. Dieses DIV positioniert und ein Clipbereich (Ausschnitt des Text) definiert. Dann bewegt man das DIV und den Clipbereich in entgegengesetzer Richtung. dadurch entsteht der Scrolleffekt.

                        Du bringst mich auf Ideen. ;) Jetzt muss ich nur noch rausfinden, wie man die Clipwerte verändert. Vielleicht mit .style.clip.top? Ich finde es raus. ;)

                        Wenn Du aber ein kaufen möchtest hat das Buch aus dem O'reilly-Verlag die bessere Referenz. Ich weiss nicht wie die Referenz jetzt im Buch von Stefan Koch in der 3. Auflage ist.

                        Ich werde mal ne Buchhandlung aufsuchen und mir das anschauen.

                        MfG Mülli

                        --
                        Viva Colonia!
                        1. Hallo!

                          Ich meinte das in Bezug auf gute nachvollziehbare Beispiele oder ähnliches.

                          Ich finde diese Kochbücher nie so gut. Die Beispiel sind oft nicht altagstauglich.

                          Und was soll da noch passieren?

                          Gar nichts. Das Ding funktioniert in allen Browsern, die ich bedienen möchte einwandfrei. Ich wollte nur ausdrücken, dass das in Bezug auf das, was man mit JS so anstellen kann noch relativ primitiv ist.

                          Man kann natürlich mit JS mehr anstellen...

                          Du bringst mich auf Ideen. ;) Jetzt muss ich nur noch rausfinden, wie man die Clipwerte verändert. Vielleicht mit .style.clip.top? Ich finde es raus. ;)

                          Mal aus einem Script von mir genommen:

                          z.B.
                          // IE und/oder Mozilla
                          document.all.ebene.style.clip = "rect(" + t + " 20 " + b + " 40)";

                          document.getElementById('ebene').style.clip = "rect(" + t + "px, 30px, " + b + "px, 0)";

                          // NN4
                          document.layers.ebene.clip.height = b;
                          document.layers.ebene.clip.top = t;
                          etc.

                          Nach meinen Erfahrungen mochte der Mozilla es mit Komma und der IE ohne Komma und ohne px. Es kann laut Errate der CSS Spez. mit oder ohne Komma geschrieben werden.

                          Die Variablen "r" und "b" können nun verändert werden und der Clipbereich verändert sich.

                          MfG, André Laugks

                          --
                          L-Andre @ gmx.de
                          1. Hallo,

                            Mal aus einem Script von mir genommen:

                            z.B.
                            // IE und/oder Mozilla
                            document.all.ebene.style.clip = "rect(" + t + " 20 " + b + " 40)";

                            document.getElementById('ebene').style.clip = "rect(" + t + "px, 30px, " + b + "px, 0)";

                            Danke, habe es damit nach einiger Frickelei hinbekommen!

                            Nach meinen Erfahrungen mochte der Mozilla es mit Komma und der IE ohne Komma und ohne px. Es kann laut Errate der CSS Spez. mit oder ohne Komma geschrieben werden.

                            Ich habe es mit px und ohne Komma gemacht. Klappt wunderbar ab IE4, Netscape 6.0 / Mozilla und Opera 7. Der einzige der im Unterschied zu meinem ursprünglichen Script nicht mitmacht ist Opera 6, weil der  idiotischer Weise gar kein clip kennt.

                            Die elegantere Lösung ist es ja ehrlich gesagt schon. :)

                            Hier zu bewundern: http://adepto.de/dateien/cscroll.html

                            So, für heute habe ich genug Javascriptcode gesehen. ;)

                            Schönes Wochenende!

                            MfG Mülli

                            --
                            Viva Colonia!
                      2. Ich hätte nur eine DIV genommen. Dieses DIV positioniert und ein Clipbereich (Ausschnitt des Text) definiert. Dann bewegt man das DIV und den Clipbereich in entgegengesetzer Richtung. dadurch entsteht der Scrolleffekt.

                        Wozu den Clipbereich? Die clip-Funktion in Javascript braucht man doch eigentlich nicht mehr, zumindest nicht für solche Zwecke - ich will hier jetzt keine grundsätzliche Diskussion lostreten.

                        Ein positioniertes Div mit overflow:hidden; reicht doch aus, dann kann ich den Inhalt des divs beliebig verschieben und es erscheint immer nur der Teil des Inhalts, der im div-Bereich liegt.

                        Hab ich mich jetzt zu kurz gefaßt?

                        Gruß
                        Avalon

        2. Hallo,

          Gute Frage! Keine Ahnung!

          Eingen wir uns auf Ja. ;-)

          Diese Methoden sind im DOM definiert.

          1. Document Object Model CSS
            http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/css.html
            insertRule: http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/css.html#CSS-CSSStyleSheet-insertRule

          Oh mein Gott, diese ekelhaften englischsprachigen W3C-Spezifaktionen sind für mich reinste Qual. ;) Jedenfalls finde ich es ausgesprochen anstrengend mich da durchzukämpfen. Aber trotzdem danke für die Links!

          Kannst du mir gute deutschsprachige Literatur empfehlen, die weit in die Tiefen des DOM vordringt und gleichzeitig halbwegs idiotensicher ist? Ehrlich gesagt hab ich mich ja erst seit deinem HTML-Unterricht ausführlicher mit Javascript befasst, aber mit Selfhtml kommt man ja diesbezüglich nicht besonders weit wie ich finde.

          MfG Mülli

          --
          Viva Colonia!