ノード生成関数
みじかめで、よさそうなのを書こうとしているけどわりとびみょうだなぁ http://subtech.g.hatena.ne.jp/cho45/20071117/1195309573 をもとにしてj
function $N (str, childs) {
if (str.nodeType) return str;
var t, cur, stack = [cur = document.createDocumentFragment()];
while (str.length) {
if (str.indexOf("<") == 0) {
if (t = str.match(/^\s*<(\/?[^\s>\/]+)([^>]+?)?(\/)?>/)) {
var tag = t[1], attrs = t[2], isempty = !!t[3];
if (tag.indexOf("/") == -1) {
child = document.createElement(tag);
if (attrs) attrs.replace(/([a-z]+)=(?:'([^']*)'|"([^"]*)")/gi,
function (m, name, v1, v2) {
child.setAttribute(name, v1 || v2);
}
);
cur.appendChild(child);
if (!isempty) {
stack.push(cur);
cur = child;
}
} else cur = stack.pop();
} else throw("Parse Error: " + str);
} else if (t = str.match(/^([^<]+)/)) cur.appendChild(document.createTextNode(t[0]));
str = str.substring(t[0].length);
}
var ret = stack.pop();
if (ret.childNodes.length == 1) ret = ret.firstChild;
if (childs) for (var i = 0; i < childs.length; i++) {
ret.appendChild(arguments.callee(childs[i]));
}
return ret;
}みたいなのにしてみた (innnerHTML は table 関係の要素を扱うとき、補完とかされてかえってめんどうくさい。)
document.body.insertBefore(
$N("<div/>", [
"<p>aaa<em>foobar</em></p>",
document.createElement("br"),
"<p><a href=''>foobar</a></p>",
]),
document.body.firstChild
);みたいにする。文字列だけあつかえてもあんまり嬉しくないので、DOM オブジェクトを混在させてもいいように
ただ、あんまり読みやすくない。jQuery みたいなのはいいんだけど、特殊なオブジェクトをつくって DOM の基本メソッドを全部実装しないといけないから長くなる……