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;
};

Posted in  | Tags , , , ,  | 3 comments | 1 trackback