Generowanie HTMLa w javacripcie
Posted by Piotr Sarnacki Sun, 16 Sep 2007 10:43:00 GMT
Czasami bywa tak, że jakaś wyższa siła każe nam generować duże ilości HTMLa. Wygląda to dość nieładnie:
var el = document.createElement("div");
el.setAttribute('id','elementId');
el.setAttribute('class','someClass');
document.body.appendChild(el);
Stworzony został jeden element. A jakby elementów było 10? I każdy miałby po parę atrybutów? Masakra.
Na szczęście powstają różnego rodzaju DOM buildery. Od wersji 1.5.1 użytkownicy prototype’a będą mogli cieszyć się jego dobrodziejstwami. Jeżeli chodzi o jQuery to znalazłem dość fajną implementację. W komentarzach jest też inna wersja, która mi osobiście bardziej odpowiada.
$.create(
'table', { 'class':"MyTable" }, [
'tbody', {}, [
'tr', {}, [
'td', { 'class':"MyTableCol1" }, [ "howdy" ],
'td', { 'class':"MyTableCol2" }, [
"Link:", 'a', { 'class':"MyLink", 'href':"http://www.example.com" }, ["example.com"] ] ] ] ]
).appendTo(document.body);
Całkiem ładnie to wygląda. używając createElement wyszłoby pewnie ze 20 linijek.
Są oczywiście inne implementacje, które nie wymagają jQuery czy prototype’a, przydatne szczególnie w przypadku różnego rodzaju widgetów. Odsyłam do wujka G ;)
Tak jak obiecałem, wrzucam ostateczne wersje zaproponowanych w powyższym linku funkcji. Teraz powinno działać bez zarzutu.
jQuery.create = function() {
var ret = [], a = arguments, i, e;
a = a[0].constructor == Array ? a[0] : a;
for(i=0; i<a.length; i++) {
if(a[i+1] && a[i+1].constructor == Object) { // item is element if attributes follow
var tag = a[i];
attrs = a[++i];
if(jQuery.browser.msie && (attrs.name || attrs.checked)) {
tag = '<' + tag + ' ' + (attrs.name ? 'name="' + attrs.name + '" ' : '')+ (attrs.checked ? "checked" : " ") +'>';
if(attrs.name) delete attrs.name;
if(attrs.checked) delete attrs.checked;
}
e = document.createElement(tag);
jQuery(e).attr(attrs); // apply attributes
if(a[i+1] && a[i+1].constructor == Array) jQuery(e).append(jQuery.create(a[++i])); // optional children
ret.push(e);
} else { // item is just a text node
ret.push(document.createTextNode(a[i]));
}
}
return ret;
};
jQuery.tpl = function(json, tpl) {
var ret = [];
jQuery.each(json.constructor == Array ? json : [json], function() {
var o = jQuery.create(tpl.apply(this));
for(var i=0;i<o.length;i++) ret.push(o[i]);
});
return ret;
};

