属性文字作成関数
同じことを何度も書く確率が高いのはタグソースを作成する部分かと思ったりします…の続きです
PHPでもjavascriptでもプログラム中にタグ記述を文字列作成することが多いはずなので、それを効率化する関数アイデアについて紹介します。
属性文字列を作成する関数を作ってみる
前記事で、HTMLタグ記述を作成する関数を作ってみましたが、その時に属性関連はそのまま文字列で記述するようになっていました。 属性の場合、「頭に半角スペース」「属性名=」と「"」を記述することになりますが、特に「"」をいちいち書くのが面倒、という考えから属性部分も関数で作れるようにしてみます。
属性文字を返すサブ関数を用意
作ろうとするサイトで必要となる属性文字列も必要となれば増やせるように、タグ文字と同様に関数で用意してみます。
function r_zt(n){
var a=[
'id',//0
'class',//1
'style',//2
'name',//3
'alt',//4
'title',//5
'type',//6
'width',//7
'height',//8
'src',//9
'href',//10
'target',//11
'value',//12
'checked',//13
'selected',//14
''
];
return a[n];
}
番号指定で属性文字を返す関数です。必要になった属性名を追加しやすくするために縦に記述しています。 ※サンプルなので、思いついたものを適当に並べています。
属性文字列作成関数 mk_z(n[,v,t])
引数について
v以降は省略可とします。
n : r_zt(n)用のタグ番号
v : 属性の値
※ v は省略可。省略時は「alt = ""」の使い方のように空文字
t : checked = "checked" や selected = "selected" のようなものに対応するためのタイプ選択
t = 0 や省略時は普通に属性作成。 t=1 の場合は属性名 = "属性名"、とするようにします。
function mk_z(n,v,t){
var z=r_zt(n);
v_ck(v)||(v='');
v_ck(t)||(t=0);
return ' '+z+'="'+((t)?z:v)+'"';
}
関数の使い方
引数 v , t は後ろから順に省略できます。
※tだけ利用して、vを省略と同じ状態にしたい時は v に 0 を指定します。
mk_z(4)と呼ぶと、「 alt=""」が返ってきます
通常はtを省略して使います
mk_z(5,'画像イメージ') → 「 title="画像イメージ"」
mk_z(7,'300') → 「 width="300"」
t=1指定で、属性=属性の表示になります。(vの文字列は無視します)
mk_z(13,0,1) →「 checked="checked"」
mk_z(14,0,1)→「 selected="selected"」
vは使わないので何でもokですので通常は 0 を渡します。
mk_z 関数のテスト
例1:mk_z(0,'test') → [ id="test"] の文字列が返ります (引数 t 以下を省略)
例2:mk_z(2,'btsty') → [ style="btsty"] の文字列が返ります (引数 t 以下を省略)
例3:mk_z(7,300) → [ width="300"] の文字列が返ります (引数 t 以下を省略)
例4:mk_z(4) → [ alt=""] の文字列が返ります (引数 v 以下を省略)
例5:mk_z(13,0,1) → [ checked="checked"] の文字列が返ります
例6:mk_z(14,0,1) → [ selected="selected"] の文字列が返ります
プログラム中で使っている関数【v_ck(s)】は前回作った『引数があるかないかをチェックする時にも使える値チェック関数』です。
引数を省略して関数を読んだ場合で、その省略された引数値をチェック時に、0を返します。
function v_ck(s){
return (s===' ')?1:(s==="")?0:(s===void(0))?0:1;
}
今回の記事では汎用的な形で作りましたが、[ checked="checked"] や [ selected="selected"] のように属性名により値が必ず決まる場合には、tによる特殊記述指定のようなことをせず、(今回の場合)n = 13 や n = 14 だったら自動で属性名を属性値にする、というように作ってしまうのもいいかと思います。
前記事のソース作成関数を更新してみます
せっかく作ったので、前回のタグ作成関数で今回の属性文字作成関数を使ってみます。
※この関数で使うことになったので、r_zt(n)の配列の[0]と[1]は必ず[id]と[class]とします。変更してしまうと出力結果がおかしくなっていまいます。
前回ソース
function mk_tag(n,t,d,i,c,o){
v_ck(t)||(t=0);
v_ck(d)||(d='');
v_ck(i)||(i=0);
v_ck(c)||(c=0);
v_ck(o)||(o=0);
var s='<',h=r_tt(n);
if(t==2){s+='/'+h;}
else{
s+=h;
if(i)s+=' id="'+i+'"';
if(c)s+=' class="'+c+'"';
if(o)s+=o;
if(t==1)s+='>'+d+'</'+h;
}
return s+'>';
}
↓
function mk_tag(n,t,d,i,c,o){
v_ck(t)||(t=0);
v_ck(d)||(d='');
v_ck(i)||(i=0);
v_ck(c)||(c=0);
v_ck(o)||(o=0);
var s='<',h=r_tt(n);
if(t==2){s+='/'+h;}
else{
s+=h;
if(i)s+=mk_z(0,i);
if(c)s+=mk_z(1,c);
if(o)s+=o;
if(t==1)s+='>'+d+'</'+h;
}
return s+'>';
}
属性記述についての考察
せっかくの属性文字列記述関数なので、よく使いそうなものを考えてみます。
例えば、[width] [height] [alt] [src] は [img]タグソースの時に使うかと思いますが、それはimgタグ作成関数などを作った時にその中で作った関数を使い、引数として値を呼ばせる作り方が考えられます。
その他に汎用のタグでよく使うものとして、[style] を直接タグに記述する、などの使い方があるかと思います。
style属性の場合、[ style="xxx:yyy;aaa:bbb;"] のような複数の要素を指定する形になったりします。
ということで、style属性記述を楽にするためにまた関数を作ってみます。
プログラム中で何度も、width や background-color 等の文字列を記述しないですむようにしたいからです
style属性記述作成関数
styleのプロパティ文字を返す関数
※width や height は属性文字と同じ記述ですが、こちらはプロパティ文字として用意しています。
function r_cp(n){
var a=[
'width',//0
'height',//1
'top',//2
'right',//3
'bottom',//4
'left',//5
'font-size',//6
'display',//7
'background-color',//8
'color',//9
''
];
return a[n];
}
style文字列作成関数
function st_ss(n,v){
v_ck(v)||(v='');
return r_cp(n)+':'+v+';';
}
スタイル記述は複数のプロパティを書くことが多いので、もっと楽になるように、複数の記述を配列指定できる関数を作ってみます。
そのために、配列かどうかをチェックする関数を作っておきます。
配列判定関数
function is_a(a){
return (a instanceof Array)?1:0;
}
配列データ版のstyle文字列作成関数
function st_sa(a,b){
var s='',f=is_a(a)*is_a(b); //aとbがどちらも配列なら、f=1,それ以外は0になります。
if(f){
a.forEach(function(v,i){s+=st_ss(v,b[i]);});
}
return s;
}
※ 変数 f を使わず、if判定のところで [is_a(a) * is_a(b)] をすればいいのですが、分かりやすくそう書きました。
※ 配列処理なので、変数が増える for 文ではなく、forEach を使っています。
これで、style属性の文字が1個だけの場合は [st_ss] 、複数の場合は配列で引数値を渡して[st_sa]を使うという感じになりました。
例:属性文字作成関数とstyle属性文字作成関数で、スタイル属性文字列を作ってみます。
[ style="width:300px;"]を作りたい。var text = mk_z(2,st_ss(0,'300px'));
[ style="width:300px;height:50px;background-color:rgba(100,0,0,0.5);display:inline-block;"]を作りたい。var a=[0,1,8,7],b=['300px','50px','rgba(100,0,0,0.5)','inline-block'], text = mk_z(2,st_sa(a,b));
[st_ss] 関数のテスト
[st_sa] 関数のテスト
値指定するだけでタグ記述に関する文字列を作る関数をいくつか作ってみましたが、その一番のキモとなっている部分は、数値を渡すと文字列を返すだけの単純で簡単な文字列関数だった、と思っていただけるかと思います。
使っている文字列関数は、タグソースの場合は、前回のタグ文字用の [r_tt(n)]、属性文字は [r_zt(n)] 、styleのプロパティ文字は [r_cp(n)] です。
ということは、もっとマニアックにタグソース記述の効率化を求める場合、style記述と同様に、色指定の rgba や rgb などの文字列を作る関数を作ってみたり、display の block , none , inline-block , table … のような文字列も同様の [r_xx(n)] という文字を返す関数を用意して数値指定するだけでいい形にすると楽ができるようになる、などと考えることができます。プログラムも単に文字を返すだけ、とか、文字列結合して返すだけ、というものなので、簡単に作れるかと思います。
このように、文字列を返す関数や、文字列を作る関数で記述を効率化する、というのが前回、今回の記事のテーマです。
色指定文字を返す関数例
a = [100,10,50,0.5] のように rgba の値を配列で渡します。
function m_c(a){
var f=is_a(a),l=_l(a),s=f?((l===4)?'rgba(':'rgb('):'';
if(l<3){l=a[0];a[1]=l;a[2]=l;}
f&&a.forEach(function(v,i){s+=(i===0)?v:','+v;}),(s+=');');
return s;
}
//汎用として作っておくと便利な文字列や配列の length を返す関数
function _l(a){return a.length;}
配列 a の値の数が4つの時は [rgba: 3つの時は [rgb] になります。
1個だけ(※2個の場合も)値をいれた配列を渡すと、同じa[0] の値をrgb で三つ記述します。
※自分で使うものなので 4個以上入れた場合のチェックは省略しました。(配列の値があるだけrgbで記述します)
[m_c] 関数のテスト
displayスタイル専用の文字列
function r_dt(n){
var a=[
'none',//0
'block',//1
'inline-block',//2
'inline',//3
'table-cell',//4
'static',//5
'relative',//6
'absolute',//7
'fixed',//8
'auto',//9
'list-item',//10
'inline-table',//11
'table',//12
'table-column',//13
'table-column-group',//14
'table-header-group',//15
'table-footer-group',//16
'table-row-group',//17
'table-row',//18
'table-caption',//19
''
];
return a[n];
}
色指定文字とdisplayスタイルの文字列関数を使ってみると以下のようになります。
[ style="width:300px;height:50px;background-color:rgba(100,0,0,0.5);display:inline-block;"]を作りたい。
mk_z(2,st_sa([0,1,8,7],['300px','50px',m_c([100,0,0,0.5]),r_dt(3)]));
タグ関数でソースを作ってみた例
<div id="test1" class="boxsty"
style="width:300px;height:50px;background-color:rgba(100,0,0,0.5);display:inline-block;"
title="test">
テストボックス1
</div>
というHTMLタグソースを作りたい。
var o = mk_z(2,st_sa([0,1,8,7],['300px','50px',m_c([100,0,0,0.5]),r_dt(3)]));
var s = mk_tag(1,1,'テストボックス1','test1','boxsty',o+mk_z(5,'test'));
こういうソースをプログラムで作る利点は、例えばidと要素の文字、タイトル文言にだけ連番を付加したい、というような変数をタグ中に入れる場合が考えられます。
例えば、上記のようなタグ記述を、9個作りたい、という例があった場合、普通にソース記述を書く場合は以下のようになるかと思います。
var s='',i,l;
for(i=1;i<10;i++){
s+='<div id="test'+i+'" class="boxsty"
style="width:300px;height:50px;background-color:rgba(100,0,0,0.5);display:inline-block;"
title="test'+i+'">
テストボックス'+i+'</div>'
}
プログラム中で、タグ記述に変数を埋め込む部分、[id="test'+i+'" class]のような["]と[']が並ぶような記述がタグ記述中にあると、打ち間違いをしてても気づきにくいような気がします。(個人的に)
色で塗り分けていない上記ソース中で変数 i の位置を探す時、ハズキルーペを使わないと、『文字が小さすぎてよめなぁあああい!』とK・W氏に激高されてしまうかもしれません。(※あくまで個人的な感想です)
PHPの場合の文字結合は js の [+] ではなく、[.] なので余計に分かりづらい気がするので、なんとなく半角スペースを入れて分かりやすくしようとして、余計にキーを打つことが多くなってしまったり…
関数を使うと以下のようになります
var i,l,s='',o = mk_z(2,st_sa([0,1,8,7],['300px','50px',m_c([100,0,0,0.5]),r_dt(3)]));
for(i=1;i<10;i++){
s+=mk_tag(1,1,'テストボックス'+i,'test'+i,'boxsty',o+mk_z(5,'test'+i));
}
ハズキルーペ、ではなくて…関数を使うと、引数に変数をくっつけてるだけなので、分かりやすいかと思います。(個人的に)
属性文字も複数指定ができる関数も用意してみる
スタイル値と同様に、属性文字も、タグによっては ID や class 以外にいろいろ複数個、付加することも多いかと思います。
なので、属性文字も配列の引数値で複数を一気に作れる関数も作ってみます。
属性文字列作成関数引数配列版 mk_za(a,b[,c])
単純に、[mk_z(n,v,t)] の引数値を配列 a , b , c にしたものです。※cのみ省略可能とします。
function mk_za(a,b,c){
var s='',f=is_a(c);
if(is_a(a)){
a.forEach(function(v,i){s+=mk_z(v,b[i],f?_pi(c[i]):0);});
}
return s;
}
//汎用として作っておくと便利なparseIntした値を返す関数
function _pi(n){
return parseInt(n);
}
使用例:a = [5,1,0] , b = ['test','zcl','zid'] , c 省略で呼ぶと、
[ title="test" class="zcl" id="zid"] という文字列が返ります。
使用例:a = [3,12,13] , b = ['ckb',1,0] , c = [0,0,1] で呼ぶと、
[ name="ckb" value="1" checked="checked"] という文字列が返ります。
[mk_za] 関数のテスト
プログラム中のソース記述を楽にする方法
今回は属性関連文字とスタイル、その中のdisplayの値等の文字列関数を用意してみました。 テーマは記事中に書きましたが、とにかく、記述ミスを減らして楽をする、そのために、文字列関数や文字列を作ってくれる関数を用意しておくと便利、というご提案でした。
こんな感じでjavascript中でソースを作ってみると…(※出力をフォームに出すので分かりやすいように改行を入れています)
s,f=mk_tag,
a=['boxsty','hsty1','lsty','lbsty'],
r='\n';
s=
f(4,1,
r+f(9,1,'見出し1A',0,a[1])
+r+f(3,1,'紹介文')
+r+f(1,1,
r+f(5,1,
r+f(7,1,'list1',0,a[2])
+r+f(7,1,'list2',0,a[2])
+r+f(7,1,'list3',0,a[2])
+r
,0,a[3])+r
,0,0,mk_z(2,st_sa([0,8],['300',m_c([100,200,100])])))
+r+f(3,1,'説明文')+r
,'id_1',a[0],mk_z(2,st_ss(7,r_dt(1))))
+r+f(4,1,
r+f(9,1,'見出し1B',0,a[1])
+r+f(3,1,'紹介文2')+r
,'id_2',a[0],mk_z(2,st_ss(7,r_dt(0))));
改行無しの場合
s=
f(4,1,
f(9,1,'見出し1A',0,a[1])+f(3,1,'紹介文')
+f(1,1,
f(5,1,
f(7,1,'list1',0,a[2])+f(7,1,'list2',0,a[2])+f(7,1,'list3',0,a[2])
,0,a[3])
,0,0,mk_z(2,st_sa([0,8],['300',m_c([100,200,100])])))
+f(3,1,'説明文')
,'id_1',a[0],mk_z(2,st_ss(7,r_dt(1))))
+f(4,1,
f(9,1,'見出し1B',0,a[1])+f(3,1,'紹介文2')
,'id_2',a[0],mk_z(2,st_ss(7,r_dt(0))));
同じ記述をしているような部分を javascript や PHP で楽にするような関数を自作して、HTMLソースを関数の入れ子と引数値で作ることに慣れると、 HTMLを直接記述して [<] [>] [""] [/] などを大量に記述するのが面倒になってしまったりするかもしれません。
PHP等では、テキストファイルに番号とオプション記述などを書き、それを読み込んで自動的にソースを作成する、といった感じで応用して作ったりしていると、その発展として、気がつくとCMSっぽいものを作っていたことに気づく、ということになるかもしれません。
そしてCMS的なものを利用すると、テキストで用意した原稿を順に読み込み、1000ページでも2000ページでも対応可能な商品紹介ページを一瞬で大量に作成できるツールなども作れたりします。
そういったプログラムの中身は単なる文字列結合や置き換え処理だけだったりします。
原森webのサイトでは、前回・今回紹介したような関数(※関数名や機能は微妙に違います)を使って、
ページ読み込み時に HTML ソースをたくさん作って innerHTML しているので、よく使ったりしてるのですが、
そんな、ある意味めんどくさい web サイトを作ったりしていない人は、この記事内容の感想として、
「こんな関数作っても納品物で使うjavascriptでは使わないよ~
HTMLタグは会社に Dream Weaver の年会費支払ってもらってそれ使って作ればいいんだよ。
それよりもっと面白いもの…例えば、タイプライターみたいに文字が表示されるやつとか、
サブウインドをドラッグして動かすとかの作り方を教えろよ~」
などの感想を持つ人がいるかもしれません。
『●○と道具は使いよう』ということわざがありますように、こういうプログラムは自分が楽をする無料ツールとして自分で作ることで、スキルアップするということにもなるかと思います。
市販のツールがなくても自分で何か作れるというのは武器になるのではないかと思います。
プログラム(プログラム技術)は『依頼された納品物を作るためだけ』じゃなくて、
習得しているプログラム技術を自分の制作業務のためにいろいろ考えて作って使ってみると、
素早くミスなく楽ができ、さらに自分で作ったという達成感も感じられるので作業的に感じてしまうような仕事が楽しくなったりするかもしれません。
前回、今回の記事は、そんな提案をしてみた内容でした。
以上、長い記事を最後まで読まれたみなさん、お疲れさまでした。
ページトップへ