JavaScript で HTML を動的に作成することはよくやりますが、下記のように直球な方法のは中々面倒くさい。
var sHtml = "<table><thead><tr><th>" + sHoge + "</th></tr></thead></table>";
いろんな便利な方法があるのでしょうが、ググッても私がイメージしてたようなのは中々見つからなかったので、自分で作れないか試してみました。
var gh = {
gen: null,
/*
データ構造を元に HTML 生成。
引数は 文字列 or 数値 or ハッシュ 想定。
ハッシュは、'tag', 'inward' が予約KEYで、それ以外はアトリビュートとされる。
'inward' は 文字列 or 数値 or 配列 想定で、配列には引数と同じものを入れることが出来る。
以下はテーブル作成例。
var h = {
tag: 'table',
class: 'table table-bordered',
inward: [
{
tag: 'thead',
inward: [
{
tag: 'tr',
inward: [
{
tag: 'th',
inward: 'title1'
},
{
tag: 'th',
inward: 'title2'
},
]
}
]
},
{
tag: 'tbody',
inward: [
{
tag: 'tr',
inward: [
{
tag: 'td',
inward: 'value1'
},
{
tag: 'td',
inward: [
'value2',
{ tag: 'br' },
{ tag: 'b', inward: 'fugafuga' }
]
},
]
}
]
},
]
};
var sHtml = gh.generateHtml(h);
*/
generateHtml: function(h) {
if (typeof h == 'string' || typeof h == 'number') {
return h;
}
var sInward = null;
var sTag = null;
var aAttr = [];
for (var key in h) {
if (key == 'tag') {
sTag = h[key];
}
else if (key == 'inward') {
if (typeof h[key] == 'string' || typeof h[key] == 'number') {
sInward = h[key];
}
else {
sInward = '';
for (var i = 0; i < h[key].length; i ++) {
sInward += arguments.callee(h[key][i]);
}
}
}
else {
if (h[key] == null) {
aAttr.push(key);
} else {
aAttr.push(key + '="' + h[key] + '"');
}
}
}
if (sTag == null) {
return '';
}
var sTagS = '<' + sTag + (aAttr.length == 0 ? '' : ' ' + aAttr.join(' ')) + '>';
return (sInward == null) ? sTagS : sTagS + sInward + '</' + sTag + '>';
}
};
gh.gen = {
/* hBase をベースとして、a の要素(ハッシュ)を加えたもので HTML 生成して a に対応した配列として返す */
unite: function (hBase, a) {
var aR = [];
for (var i = 0; i < a.length; i ++) {
var h = {};
for (var key in hBase) {
h[key] = hBase[key];
}
for (var key in a[i]) {
h[key] = a[i][key];
}
aR.push(gh.generateHtml(h));
}
return aR;
},
/* 配列から tr,td 生成 */
array2tr: function (a) {
var hTr = { tag: 'tr', inward: [] };
for (var i = 0; i < a.length; i ++) {
hTr.inward.push({
tag: 'td',
inward: a[i]
});
}
return gh.generateHtml(hTr);
},
/* a 生成 */
a: function (h) {
h.tag = 'a';
return gh.generateHtml(h);
},
/* option 生成。inward は文字列想定。value 省略時は inward が入る */
option: function (h) {
h.tag = 'option';
if (! 'value' in h) {
h.value = h.inward;
}
return gh.generateHtml(h);
}
};
コメントにもありますが、入れ子になったデータ構造を渡すとHTML文字列を作成します。
img タグを作る場合とかはこんな感じでしょうか。
var sHtml = gh.generateHtml({ tag: 'img', src: 'hoge.png' });
unite は下記のように一部のデータ構造が同じものをいっぱい作るときを想定しています。
var a = [
{ name: 'hoge', value: 123 },
{ name: 'fuga', value: 456 }
];
var sHtml = gh.gen.unite({ tag: 'input', type: 'hidden' }, a).join("");
これでも多少は便利よく使えるかとは思うのですが、もっといい感じのがあるはず…とも思うので、知っていたら教えてくださいね。
##追記 2014-08-04
dankogai さんから下記を紹介していただきました。
便利すぎる…。のでこっち使ったほうが良いです。
json2dom() & dom2json()