2017年2月23日木曜日

idやname属性を使わずにエレメントを取得する関数

「<button id=btn作成>作成</button>」のような書き方が冗長だと感じていました。
「<button>作成</button>」を含むエレメントを渡すと「obj.btn作成」という形式でエレメントに参照できるようにする独自関数を作成しました。


以下、ソース
<html>
<title>getChilds</title>
<body>
<table border=1>
<tr>
<td>
<span>*制御用ボタン</span>
<button>作成</button>
<button>消去</button>
<button>追加</button>
</td>
</tr>
<tr><td>表示</td></tr>
</table>
<table border=1>
<tr>
<td>
<span>*制御用ボタン</span>
<button>作成</button>
<button>消去</button>
<button>追加</button>
</td>
</tr>
<tr><td>表示</td></tr>
</table>
</body>
<script>
CN='childNodes', iT='innerText', LEN='length', FI='firstChild'
for0L=function(arr,fun){for(var i=0,L=arr[LEN],res;i<L;i++){if(res=fun(i,arr[i])){return res}}}
forIn=function(obj,fun){var name,res; for(name in obj){if(res=fun(name, obj[name])){return res}}}
getChilds=function(){
var tagName2接頭辞={button:'btn', input:'inp', select:'sel', a:'lnk', iframe:'ifr', table:'tbl', textarea:'ta'}
var inp接頭辞={checkbox:'chk', radio:'rad', text:'inp', number:'num'}
var arr階層=[], arr階層_i=0
var get名前=function(){
var F=function(prop, v){return {prop:prop, v:v}}
var E, objNames={value:1, title:1, innerText:1}, forIn用=function(name){ return E[name] ? F(name, E[name]) : 0 }
return function(elem){
E = elem
var obj=forIn(objNames, forIn用), it=E[iT], src=E.src
if(obj){return obj}
if(src){return F('src', src.replace(/[\\\/]([^\\\/]+)$/)[1])}
}
}()
var return用obj, objクリア対象外={btn:1}
var for0L用=function(i, elem){
var name=(elem.tagName || '').toLowerCase()
if(!name){return}
arr階層[arr階層_i] = true
arr階層[++arr階層_i] = false
fun再帰(elem[CN])
arr階層_i--
// 例えば「<button>開始</button>」なら「btn開始」のような名前で参照できるようにする。
var 接頭辞 = ((name=='input' ? inp接頭辞[elem.type] : '') || tagName2接頭辞[name] || name)
var 名前 = get名前(elem)
// 名前があってもそれがiT由来で、かつ子要素を持つエレメントの場合は参照の対象外。
if(!名前 || 名前.prop!=iT || !arr階層[arr階層+1]){return用obj[接頭辞 + (名前 ? 名前.v : '')] = elem}
// 名前.vが「*」から始まる場合は「*」のみ削除する。それ以外の場合は名前.v=''とする。
if(名前 && !objクリア対象外[接頭辞] && (名前.prop!=iT || !arr階層[arr階層_i+1])){ elem[名前.prop] = 名前.v.charAt(0)=='*' ? 名前.v.replace(/^\*/,'') : '' }
arr階層.pop()
}
var fun再帰=function(cn){ for0L(cn,for0L用) }
return function(elem){return用obj={elem:elem}; fun再帰(elem[CN]); return return用obj}
}()
var cn=document.body[CN]
with(getChilds(cn[0])){
var arr0, f0=function(){ td表示[iT] = arr0 }
btn作成.onclick = function(){ arr0 = [0] ; f0() }
btn消去.onclick = function(){ arr0 = null ; f0() }
btn追加.onclick = btn追加.ondblclick = function(){ arr0 && arr0.push(1); f0() }
}
with(getChilds(cn[1])){
var arr1, f1=function(){ td表示[iT] = arr1 }
btn作成.onclick = function(){ arr1 = [0] ; f1() }
btn消去.onclick = function(){ arr1 = null ; f1() }
btn追加.onclick = btn追加.ondblclick = function(){ arr1 && arr1.push(1); f1() }
}
</script>
</html>
view raw getChilds.hta hosted with ❤ by GitHub



動作画面



これでもうidの重複とか気にしなくてOK。

0 件のコメント:

コメントを投稿