$n

mayokaraさんとこで見たノード構築関数を弄ってたら別物に。

function $n(name /*, [[attr], child0, child1, ...] */){
  var d = this.createElement ? this : this.document || document,
  e = d.createElement(name), a = Array.prototype.concat.apply([], arguments),
  x = a[1], o = {}, l = a.length, i, k;
  if((i = x ? x.toString === o.toString : 0))
    for(k in x) o[k] || e.setAttribute(k, x[k]);
  while(++i < l)
    e.appendChild((x = a[i]) && x.tagName ? x : d.createTextNode(x));
  return e;
}

document.body.appendChild(
  $n('div',
     $n('h1', 'hoge'),
     $n('div',
        $n('a', {href: 'fuga.htm'}, 'piyo'),
        $n('pre', $n)),
     $n('iframe')));
  • 使う document を指定可能に
  • Duck Typing もどき
  • IE

これだけだと大して嬉しくないので Groovy の MarkupBuilder とか AppJet の tags っぽく書けるようにする。

function $N(names, doc){ doc || (doc = this);
  var tags = names.match(/\S+/g), i = tags.length, o = {};
  while(i--) with({name: tags[i]}) o[name] = function(){
    return $n.apply(doc, Array.prototype.concat.apply([name], arguments)) };
  return o;
}

with(doc = frames[0].document) open(), close();
with($N('div h2 ol li a b', doc)){
  for(var i = 3, ls = []; i--;) ls[i] = li(a({href: i +'.htm'}, b(i)));
  doc.body.appendChild(
    div(h2('links'), ol(ls, ol(ls[0].cloneNode(true)))));
}

そこそこ快適。