私のダイナミックjavascriptオブジェクトはDOM元素のジェネレータになります.
5994 ワード
06年にobjectをDOM元素に変換するジェネレータを書いたことがありますが、転職してからしばらくjsを書かないとコードが見つかりません.しかし、最近は仕事が必要なので、もう一つ書き直しました.でも今は多くのjsコードバンクがこの技術を実現したようです.もう新鮮ではありません.
コードの原理は簡単です.つまり、簡単なjsオブジェクトです.その中のnodeNameフィールド値からdocument.create Element()を呼び出してDOM要素を生成し、jsオブジェクトの残りのフィールド値を新たに生成したDOM要素に設定します.まずデモコードを見て、表を生成するために、各セルに一つのcheckboxを保存します.
var table = {nodeName: "table", className: "selection", children:[]};
var ctrls;
for(var i = 0; i < infos.length; ++i)
{
if( i % 5 == 0 )
{
var row = {nodeName: "tr", children:[]};
ctrls = row.children;
table.children.push(row);
}
ctrls.push({nodeName: "td", className: "select_project", children:[
{nodeName:"input", "id": "proj_" + infos[i].id, name:"selproj", "type": "radio", value:infos[i].id, onclick: fnOnProjectCheck}
, {nodeName: "label", "htmlFor": "proj_" + infos[i].id, innerHTML: infos[i].lname}
]});
}
containor.innerHTML = "";
generateElements(containor, table);
直接の文字列でつづり合わせると、そんなにすっきりしないように見えます.使っているうちに一番便利なのは何百行もの表を作ったことです.表が長いので、20行ごとに1行の表を差し込む必要があります.この技術を使うと実に多くの重複作業が簡略化されます.
簡単に使用するには、GEnerate Elementsを呼び出して、二つのパラメータが入ってきます.一つは容器DOMオブジェクトで、一つは作成するノード記述情報です.記述情報オブジェクトは純粋なjsオブジェクトであり、ここでは、
generate Elementsのパラメータと使用の組み合わせは以下の通りです.
オブジェクトフィールドの定義:
他の話は多く話しません.コードを入れます.
// return element that generated
function generateElements(parentElem, info)
{
if( parentElem == null ) return null;
if( info == null )
{
if( parentElem.ownerDocument == document ) return null;
info = parentElem; // means single argument
parentElem = null;
}
if( info instanceof Array )
{
var elems = [];
for(var i = 0; i < info.length; ++i)
elems.push(generateElements(parentElem, info[i]));
return elems;
}
else
{
var pName = parentElem? parentElem.nodeName.toLowerCase(): "";
var nodeName = (info.nodeName||info.tagName).toLowerCase();
var fnCreate = function(p, n){return document.createElement(n);};
var fnAppend = function(p, el){p.appendChild(el);};
if( "table" == pName )
{
fnAppend = empty;
if( "thead" == nodeName )
fnCreate = function(p, n){ return p.createTHead(); };
else if( "tfoot" == nodeName )
fnCreate = function(p, n){ return p.createTFoot(); };
else if( "tr" == nodeName )
fnCreate = function(p, n){
return p.insertRow(-1);
};
else
fnCreate = empty;
}
else if( indexOfArray(["tbody", "thead", "tfoot"], pName) != -1 )
{
fnAppend = empty;
if( "tr" == nodeName )
fnCreate = function(p, n){
return p.insertRow(-1);
};
else
fnCreate = empty;
}
else if( "tr" == pName )
{
if( "td" == nodeName )
{
fnCreate = function(p, n){ return p.insertCell(-1); };
fnAppend = empty;
}
}
var elem = fnCreate(parentElem, nodeName);
if( elem )
{
// fill properties
var filtered_props = ["children", "nodeName", "tagName", "children"];
for(var prop in info)
{
if( prop.length > 0 && prop.charAt(0) != '_' && indexOfArray(filtered_props, prop) == -1)
elem[prop] = info[prop];
}
// create children
if( info.children )
generateElements(elem, info.children);
// append child
if( parentElem )
fnAppend(parentElem, elem);
}
return elem;
}
}
上記のコードには以下のような改善が必要なところがあります.