Artikel-Schlagworte: „WebDevelopment“

JavaScript DOM - einfach mit "graft()"

Donnerstag, 26. Oktober 2006

Ich habe im verlinkten Artikel eine sehr nützliche Funktion gefunden um DOM-Elemente aus simplem JSON-Pseudo-HTML Code erstellen zu lassen - graft(). Damit kann man sich endlich diese nervigen Code-Wüsten sparen, die nötig sind um selbst die simpelsten HTML Elemente per JavaScript zu generieren.
Hier ein kleines Beispiel:

var tbl = document.createElement('table');tbl.setAttribute("border",1);tbl.setAttribute("cellpadding",0);tbl.setAttribute("cellspacing",0);var tr = document.createElement("tr");
var td = document.createElement("td");td.setAttribute('valign','bottom');td.appendChild(document.createTextNode("Graft()"));tr.appendChild(td);

td = document.createElement("td");td.appendChild(document.createTextNode("makes"));tr.appendChild(td);

td = document.createElement("td");td.appendChild(document.createTextNode("this"));tr.appendChild(td);

td = document.createElement("td");td.setAttribute('style','background-color:#ff0;');td.appendChild(document.createTextNode("easier"));em = document.createElement("em");em.setAttribute('style','font-size:32px;');em.appendChild(document.createTextNode(" to do.."));td.appendChild(em);tr.appendChild(td);

tbl.appendChild(tr);

document.getElementById("mycontentdiv").appendChild(tbl);

Alles das ist nötig um eine simple Tabelle mit einer einzigen Zeile zu erstellen. Nicht nur das es eine Menge Code ist, darüberhinaus ist es auch noch sehr unübersichtlich.
Um nun das gleiche mit der graft() Funktion zu erledigen muss man nur folgendes tun:

graft(document.getElementsByTagName("BODY")[0],["table",    {border:1,cellpadding:0,cellspacing:0},    ['tbody',        ['tr',            ['td',                {valign:'bottom'},                "Graft()"            ],            ['td',                "makes"            ],            ['td',                "this"            ],            ['td',                {style:{backgroundColor:'#ff0'}},                "easier",                ["em",                    {style:{fontSize:'32px'}},                    " to do.."                ]            ]        ]    ]]);

Ist doch wesentlich übersichtlicher, und rein optisch auch näher an HTML.

Achja und hier ist übrigens die Funktion die das alles bewerkstelligt:

// from prototype.js - needed for extending the style objectObject.extend = function(destination, source) {for (property in source) { destination[property] = source[property];}return destination;}

function graft(parent, t, doc) {

// Usage: graft( somenode, [ "I like ", ['em',//               { 'class':"stuff" },"stuff"], " oboy!"] )

doc = (doc || parent.ownerDocument || document); var e;

if(t == undefined) {  throw console.log( "Can't graft an undefined value"); } else if(t.constructor == String) {  e = doc.createTextNode( t ); } else if(t.length == 0) {  e = doc.createElement( "span" );  e.setAttribute( "class", "fromEmptyLOL" ); } else {  for(var i = 0; i < t.length; i++) {   if( i == 0 && t[i].constructor == String ) {    var snared;    snared = t[i].match( /^([a-z][a-z0-9]*)\.([^\s\.]+)$/i );    if( snared ) {     e = doc.createElement(   snared[1] );     e.setAttribute( 'class', snared[2] );     continue;    }    snared = t[i].match( /^([a-z][a-z0-9]*)$/i );    if( snared ) {     e = doc.createElement( snared[1] );  // but no class     continue;    }    // Otherwise:    e = doc.createElement( "span" );    e.setAttribute( "class", "namelessFromLOL" );   }   if( t[i] == undefined ) {    throw console.log("Can't graft an undefined value in a list!");   } else if(  t[i].constructor == String || t[i].constructor == Array ) {    graft( e, t[i], doc );   } else if(  t[i].constructor == Number ) {    graft( e, t[i].toString(), doc );   } else if(  t[i].constructor == Object ) {    // hash's properties => element's attributes    for(var k in t[i]) {     // support for attaching closures to DOM objects     if(typeof(t[i][k])=='function'){      e[k] = t[i][k];     } else {      if (k == "class") {       e.className = t[i][k];      } else if (k == "style") {        Object.extend(e.style, t[i][k]);      } else {                             e.setAttribute( k, t[i][k] );      }     }    }   } else {    throw console.log( "Object " + t[i] + " is inscrutable as an graft arglet." );   }  } } parent.appendChild( e ); return e; // return the topmost created node}

Ich habe im Vergleich zur Urversion noch zwei kleine Fixes eingebaut bzgl. der “class” und “style” Attribute.

Viel Spaß damit!

Internet Explorer 6 + 7 parallel

Montag, 23. Oktober 2006

Da es M$ am Ende doch noch geschafft hat und ihren Firefox-Klon neuen Webbrowser zu veröffentlichen, gibt’s nun noch einen Kollegen mehr wenn es um das Testen von Websites geht. Netterweise hat man das Highlander-Feature beibehalten - es kann immer nur eine IE Version auf einem System laufen.
Dagegen kann man aber was tun, und es ist sogar ziemlich unkompliziert.

Wie’s geht erfährst du hier.

Wenn man danach den IE6 startet zeigt er interessanterweise die Versionsnummer des 7er an, aber davon nicht täuschen lassen - es sind noch alle Bugs vorhanden:

Weitere Tests findest du hier bei Position Is Everything.