DOM Manipulation ohne Auswirkung

shockshell

Erfahrenes Mitglied
Hallo Leute,

ich habe ein Problem mit der DOM Manipulation per Javascript.

Ich möchte an einer bestimmten Stelle ein div mit entsprechenden class und id Attribut einfügen. Das funktioniert auch. Allerdings interpretiert der Browser (bisher nur in FF ausprobiert) die Style Definition die hinter der "Class" steckt überhaupt nicht.
Wenn ich das manipulierte DOM in einer Datei abspeichere und diese Datei dann öffne, dann werden die Styleinformation ausgewertet.

Folgenden Code verwende ich zum Erstellen der Struktur:

Code:
var template='<div class="transition">hi</div>';
....
//Parsen des Templates
var xmlDoc=null;
if(detect("MSIE")){
    xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.async=false;
    xmlDoc.load(template);
}else{
    xmlDoc=(new DOMParser()).parseFromString(template,"text/xml");
}
var fragment=document.createDocumentFragment();
fragment.appendChild(xmlDoc.firstChild.cloneNode(true));

....

//ID hinzufügen
var divid= document.createAttribute("id");
divid.nodeValue = "obj1";
fragment.setAttributeNode(divid);

//Fragment zum Dokument hinzufügen
document.getElementById("canvas").appendChild(fragment);

Als Ergebnis erhalte ich folgendes Dokument:
HTML:
<div id="canvas" style="clear: both; float: left; height: 95%; width: 100%;">
   <div id="obj1" class="transition">hi</div>
</div>

Es hat den Anschein, als wenn die Attribute zwar im Text enthalten sind, aber nicht ausgewertet werden. Auch eine nachgelagerte Abfrage document.getElementById("obj1") findet das Objekt nicht.

Das Weglassen des Fragments und das direkte Hinzufügen der geparsten Struktur in das Dokument hat den gleichen Effekt.

Ich kann die Style-Definition die sich hinter dem class-Attribut befindet auch direkt als style-Attribut an das div hängen, dass hat aber leider auch keine Auswirkung.

Ich habe festgestellt, wenn ich die Manipulation über das separate Erzeugen von Elementen und Attributen (nicht über die oben angegebene Template-Variable) inkl. dem Hinzufügen in die DOM-Dtruktur ausführe funktioniert es, dass ist mir aber in Punkto Flexibilität zu starr.

Kann mir jemand sagen was ich falsch mache. Muss ich den DomParser noch irgendwie konfigurieren o.ä.?

Gruß,

Shockshell
 
Zuletzt bearbeitet:
Hallo Leute,

ich habe es jetzt etwas anders gelöst...
Da das Einfügen über manuelles Erzeugen und verketten von Objekten direkt aus dem document-Objekt heraus funktioniert habe ich mir zwei rekursive Funktionen gebastelt, die die Objektstruktur in der Variable xmlDoc traversieren und eine eigene Struktur erzeugen, basierend auf den Elementen aus dem document-Objekt. Verständnishalber hier noch der Code. Er ist nicht vollständig, da er nicht alle Node-Types berücksichtigt, sonder nur die drei häufigsten (Node, Attribute und Text)...

Code:
        processAttributes: function(node,attributes){
            for(var x=0;x<attributes.length;x++){
                var newattr = document.createAttribute(attributes[x].nodeName);
                newattr.nodeValue=attributes[x].nodeValue;
                node.setAttributeNode(newattr);
            }
            return node;
        },
        
        processChildren: function(node){
            var newnode=null;
            if(node.nodeType==3){
                newnode=document.createTextNode(node.data);
            }else{
                newnode=this.processAttributes(document.createElement(node.nodeName),node.attributes);
                for (var x=0;x<node.childNodes.length;x++){
                    newnode.appendChild(this.processChildren(node.childNodes[x]));
                }
            }
            return newnode;
        },
        
        
        createDOMFromTemplate: function(template){
            var xmlDoc=null;
            if(detect("MSIE")){
                xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
                xmlDoc.async=false;
                xmlDoc.load(template);
            }else{
                xmlDoc=(new DOMParser()).parseFromString(template,"text/xml");
            }
            
            document.createElement(xmlDoc.firstChild.nodeName);
            
            return this.processChildren(xmlDoc.firstChild);
        }

Wer sich über die komische Function Definition wundert sei auf Dean Edwards verwiesen: http://dean.edwards.name/
Achtung: Der IE-Part funktioniert noch nicht...

Gruß,

Shockshell
 
Zuletzt bearbeitet:
Danke für deine Lösung :)

Um auf die Problematik einzugehen:
Du erzeugst ja ein neues Dokument, und versuchst, dieses (bzw. einen Teil davon) in ein anderes zu kopieren.
Das ist theoretisch möglich, zumindest so vorgesehen.
(Das mit dem documentFragment kannst du dir erspaen, der Parser erzeugt ja schon ein Document).

Aufs Wesentliche zusammengefasst sollte also jenes ausreichen:
Code:
var template='<div class="transition">hi</div>';
xmlDoc=(new DOMParser()).parseFromString(template,"text/xml").documentElement;
Node = document.importNode(xmlDoc,true);
Node.setAttribute('id','obj1');
document.getElementById("canvas").appendChild(Node);

(beachte dabei den Zeiger auf documentElement, dieser liefert dir den ROOT-Knoten des Dokuments)
Die Methode importNode ist vom w3c vorgesehen, um Knoten eines fremden Dokumentes in einem anderen als solches verfügbar zu machen....dadurch wird das ownerDocument des Knotens geändert in das Dokument, wo er benötigt wird.

Nun der Haken: Firefox kann das einfach noch nicht(geschweige denn der IE :))

Dazu sagt das w3c:
Q:How can I copy a node or subtree from one document to another?

A: DOM Level 2 defines an importNode() method that performs this operation. It is up to the implementation to do this in a standard way that works across implementations or in a more efficient way that uses knowledge of that implementation's data structures. If you're working with a Level 1 DOM, you have to copy the content manually.
 
Hallo Sven,

danke für Deine Antwort. Da bin ich jetzt mal wieder etwas schlauer. Irgendwie etwas frustrierend das so etwas triviales noch nicht in den Browsern enthalten ist...

Gruß,

Marcus.
 

Neue Beiträge

Zurück