原森情報技術研究所 WEBコンテンツ企画・制作・運営・サポート / 兵庫県 神戸市 明石市 /

タグ文字作成関数

同じことを何度も書く確率が高いのはタグソースを作成する部分かと思ったりします

PHPでもjavascriptでもプログラム中にタグ記述を文字列作成することが多いはずなので、それを効率化する関数アイデアについて紹介します。

web関連のプログラムで必ずやってること

web関連のプログラムでは、最後の出力部分でHTML記述をしたものをアウトプットすることが多いかと思います。
javascriptでは主に、ID指定のinnerHTMLでタグ付きの文字列をwebサイトに出力したりすることも多かったりしますし、 PHPなどでwebサイトを作っている場合も最終結果はテンプレートにいろいろ追加した後のHTMLソース文字列をprintすることで画面表示したりしてるかと思います。
世にあるいろんなCMSやjavascriptで自作した時も、またjqueryプラグインを作ったりする時も、大抵HTML記述を文字列に書いたりしてる場合が多いような気がしてます。

そんなときに、例えば、(以下はjavascriptの記述で書きます)
for(i=0;i<l;i++){str+='<span id="id_'+ i + '" class="orz">'+ data[i] +'</span><br>'}
なんて感じで、for文使って同様のタグ記述をなるべく短くするように書いてたりするのではないかと思ったりします。
(原森もそんな感じでした…)
※jQueryにも一応[ .html() ]というのがあるようですね、よく知らないけど…
※今回はHTMLタグソース記述で文字列作成しているものを関数化する例なので、jsのdocument.createElement等は使いません。文字列作成処理のみになります。

プログラム中でHTMLタグソースを作成している例

「switch文でソースを作成している例」

switch(n){
case 0:str='<span style="color:red;">'+ value +'</span>';break;
case 1:str='<span style="color:blue;">'+ value +'</span>';break;
case 2:str='<span style="color:green;">'+ value +'</span>';break;
}

というように普通にswitch文でソース記述を並べていたり、
そんな場合でも、共通するものが多い時は…

switch(n){
case 0:c='red';break;
case 1:c='blue';break;
case 2:c='green';break;
}
str='<span style="color:'+c+';">'+ value +'</span>'

caseの部分に同じソース記述をせず、異なるデータだけを変数にしたので、タグを書いてるのは一文だけになってますけどなにか?とかの場合もあるかと思います。
この例の場合は c = ['red','blue','green'][n]; とする場合もあるかもしれませんが…。

「ifelse文でソースを作成している例」

if(f==0){
 str='<p class="o_o">'+data+'</p>';
}
else if(f==1){
 str='<p><span style="color:red;">'+data+'</span></p>';
}
else{
 str='<span class="p_q">'+data+'</span>';
}

のような、タグの種類が異なるのでそのまま作ってる感じとか

「タグの入れ子が複雑なブロックソースを作成している例」

str ='<div class="orz">';
str+='<h3>'+itemname+'</h3>';
str+='<div class="o_o"><span class="t_t">'+data1+'</span></div>';
str+='<div class="p_q"><span class="e_e">'+data2+'</span></div>';
str+='</div>';

のような、普通に出力したいブロックのタグを作ってる感じとかを、プログラム記述時に少しだけ楽するために、

var s1='<div',s2=' class="',3='">',s4='<span';
,s5='</span>',s6='</div>',s7='h3>';
str =s1+s2+'orz'+s3;
str+='<'+s7+itemname+'</'+s7;
str+=s1+s2+'o_o'+s3+s4+s2+'t_t'+s3+data1+s5+s6;
str+=s1+s2+'p_q'+s3+s4+s2+'e_e'+s3+data2+s5+s6;
str+=s6;

などにしてみたり…。原森も昔はこんな風に、誰が見ても(自分でも)すぐに理解できないような、刹那的な楽をする記述をやってたり…)
これ、あとで修正とか出てくると、パズルゲームみたいになるので大変なんですよね…。(作っている時はすぐ頭が回転して対応可能だけど、時間が経つと忘れてしまう)

打ち間違いや見間違いによるエラーが発生しやすい

プログラムソース中にタグ記述する時の利点。

プログラムソース中にタグ記述する時の利点は、そこでタグソースを作っているのがそのまま記述されているからわかりやすい、ということです。
つまりは他人が改定する時にこのソースをこう修正すればいい、と判明しやすい、と言う点かと思います。
ですがプログラム中のタグソースには必ず変数文字が混ざっているので注意が必要です。
変数記述がないのなら、テンプレートのHTMLタグに書くだけでいいはずですので…。

プログラムソース中にタグ記述する時の欠点。

phpでCMS作る仕事に参加してた経験で言えば、webプログラム開発でのエラーは、似たような記述 (span div li など) が大量に並んでたりした場合に、変数名の打ち間違い、タグの閉じ部分の見間違いによるHTML入れ子構造の記述ミスなどで、出力時にエラーが発生してしまうことがあったり、また、出力したいHTML部分の修正時にプログラム内で書いてるタグソースに変数などが混ざっているので修正しづらくて時間がかかってしまう、などの問題点もあるのではないかと思ったりします。
感想としては、span や div よりも、[<][>]を何千個書かすねんなん!と言う感じでした。そもそもHTMLタグでも[<][>]を記述してるのにプログラム中にもこれ、いっぱい書かなきゃいけないのか…などと思ってしまいます。プログラムは楽をするためのものなのに。

さっきの「異なるデータだけを変数にしたので、タグを書いてるのは一文だけになってますけどなにか?」の例で、その部分ではタグ記述しているのは1文だとしても、プログラム全体で何百個何千個の [タグ用の<]や[タグ用の>]、[span]とか[div]とか[class]とか同じ文字を何度も書いてんねん!(いきなり大阪弁)って感じで自分につっこんでしまったりしたことはありませんか?過去の原森は新規のプログラムやHTML作成に取り掛かるたびにそんな感じになりました。
そこでプログラムの場合は、後で見たら意味不明な「str += s1 + s2+ 'o_o' + s3 + s4 + s2 + 't_t' + s3 + data1 + s5 + s6 ;」というわけのわからない楽の仕方をしていたり…。その時の自分に今思いついている単純なアイデアを教えてあげたくなってしまいます。

タグソース作成関数とか作ると、かなり楽になります

楽する方法は、関数に番号とかその他の必要な情報を渡せば勝手にソース作って返してくれるような、HTMLソース文字列作成関数を作ることではないかと、ここ数年は考えています。
制作しているサイトの仕様によって、使わないタグ記述は用意しない方向でいろいろ専用で作ればいいのですが、汎用的なひな形的サンプルをjavascriptで以下に書いてみます。(原森webで作って使ってる関数とは微妙に異なりますが基本は同じです)

タグ文字を返すサブ関数を用意

タグ文字はこの関数で番号指定することで文字列を取得して使うことにします。
これでプログラム中に、何百個もspanとかbrとかが書いてないようにしてしまいます。最近ではよく使うことになってるはずのsectionとかも、打ち間違えの心配がなくなります。

function r_tt(n){
var a=[
'br',//0
'div',//1
'span',//2
'p',//3
'section',//4
'ul',//5
'ol',//6
'li',//7
'a',//8
'h1',//9
'h2',//10
'h3',//11
'h4',//12
''
];
return a[n];
}

番号指定でタグ文字を返すだけの関数です。必要になったタグを追加しやすくするために縦に記述しています。
上例のn=13で空文字返す仕様は原森の好み(追加時のコピペがしやすくなるだけ)なので特に意味はないです。
自分で使うための部品なので、エラーチェック(上の例ではnが14以上の場合等)やその処理は不要かと思います。

処理を簡略化するためのサブ関数

function v_ck(v){
return (s===' ')?1:(s==="")?0:(s===void(0))?0:1;
}

引数があるかないかをチェックする時にも使える値チェック関数です。 引数などを渡してチェックしてみて、無い場合にはjsの場合、v===void(0)で引っかかって0を返します。
※PHPの場合は関数の引数省略して呼んだりして、呼ばれた関数の方で値が無ければ初期値を入れる記述ができますが、javascriptは最近そういう記述が対応可となったばかりで、対応ブラウザがIE以外のようなので、まだ、こういう関数を用意する必要があるかと思います。

タグ文字列作成関数 mk_tag(n[,t,d,i,c,o])

※[ ]内の引数は後ろから順に省略可能です。
n:r_tt(n)用のタグ番号
t:type
※t:[0又は省略=開始タグのみ][1:開始と閉じタグ][2:閉じタグのみ]
d:tが1の時に使うタグではさむ文字列等
i:id名
c:class名
o:その他属性ソース記述
※i~oで属性記述が不要なものは、後ろから省略、又は数値の0を渡します

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+'>';
}

上記関数の使い方の例

t~oは後ろから順に省略できます。mk_tag(0)と呼ぶと、「<br>」が、mk_tag(1)なら、「<div>」が返ってきます

d以降省略で
mk_tag(2,2)→「</span>」、mk_tag(3,2)→「</p>」
こんな感じに閉じタグを作成したり…。

oを省略した場合の例:mk_tag(1,1,'test','id_1','orz')などなら、
「<div id="id_1" class="orz">test</div>」が作成されます。

idは不要でclassは指定する、という場合、省略処理に使っている0を渡します。
mk_tag(2,1,'test',0,'orz') → 「<span class="orz">test</span>」

oはいろんな属性を記述するためのものです。
[name=] [checked=checked] [title=] [alt=] [data-***=] などいろんなものがありますので、 とりあえず汎用的に [id] [class] とその他、という形にしています。
例:o=' data-test="test"'; mk_tag(1,0,0,'id_1',0,o) →
「<div id="id_1" data-test="test">」となります。

ソース記述作成がこんな感じに変わります例1

for(i=0;i<l;i++){str+='<span id="id_'+ i + '" class="orz">'+ data[i] +'</span><br>'}

↓ 2:span , 0:br

for(i=0;i<l;i++){str+=mk_tag(2,1,data[i],'id_'+i,'orz')+mk_tag(0);}

ソース記述作成がこんな感じに変わります例2

switch(n){
case 0:c='red';break;
case 1:c='blue';break;
case 2:c='green';break;
}
str='<span style="color:'+c+';>"'+ value +'</span>'

↓ 2:span ※サンプルのswitch文のような内容の場合は配列の方が短くなるので、話はそれますが、配列化しています。

var o=' style="color:'+['red','blue','green'][n]+';"';
str=mk_tag(2,2,value,0,0,o);

変数oにその他ソース部分を記述しているのはサンプルが見やすくするためで、 普通なら関数の引数指定部分に直接記述するかもしれません。

ソース記述作成がこんな感じに変わります例3

if(f==0){str='<p class="o_o">'+data+'</p>';}
else if(f==1){str='<p><span style="color:red;">'+data+'</span></p>';}
else{str='<span class="p_q">'+data+'</span>';}

↓ 3:p , 2:span ※ 関数を変数xに入れてショートコード化しています。当然関数を入れ子にできます。

var x=mk_tag;
if(f==0){str=x(3,1,data,0,'o_o');}
else if(f==1){str=x(3,1,x(2,1,data,0,0,' style="color:red;"'));}
else{str=x(2,1,data,0,'p_q');}

↓ javascript的にショートコード化

var a=[3,3,2],q=['o_o',0,'p_q'][f],p=(f==1)?mk_tag(2,1,data,0,0,' style="color:red;"'):data;
str=mk_tag(a[f],1,p,0,q);

↓もっとショートコード化した例

str=mk_tag([3,3,2][f],1,((f==1)?mk_tag(2,1,data,0,0,' style="color:red;"'):data),0,['o_o',0,'p_q'][f]);

※pを直接記述はわかりやすくなるように()をわざと付けてます。

ソース記述作成がこんな感じに変わります例4

str ='<div class="orz">';
str+='<h3>'+itemname+'</h3>';
str+='<div class="o_o"><span class="t_t">'+data1+'</span></div>';
str+='<div class="p_q"><span class="e_e">'+data2+'</span></div>';
str=+'</div>';

↓ 1:div , 2:span , 11:h3

var x=mk_tag;
str =x(1,1,
x(11,1,itemname)
+x(1,1,x(2,1,data1,0,'t_t'),0,'o_o')
+x(1,1,x(2,1,data2,0,'e_e'),0,'p_q')
,0,'orz');

のように関数の入れ子で記述を短くすることができます。
このサンプルのように、(これはそれほど長くないですが)プログラム内で大量のHTMLソースをずらずらと記述している場合に ソース記述を作成する関数を用意すると、修正やエラーチェックがかなり楽になるのでないかと考えます。タグ記述で[>]を書き忘れてるとか、閉じタグを忘れてるなど…
※途中でいろいろ属性記述にデータ埋め込みや置き換えをしまくってる時に、 [str+=]などで1文を複数に分けて文字列作成したりしてると、 案外忘れてたりする場合があったり…
とかのミスはなくなるのではないかと思ったりします。

上記関数のテスト

動作テスト:mk_tag(n,t,d,i,c,o)
単純テスト
n = t =

文字列: (d)
ID名: (i)
クラス: (c)
その他: (o)

省略の選択


タグ作成結果:

ソース記述についてもっと楽にする方法について

属性関連を専用で作る関数を用意したり、aタグ用、imgタグ用などを上記のような関数を使って用意すると、プログラムで出力するソースを楽に作成することができるかと思いますので、いろいろ作ってみるのもよいのではないでしょうか?などと思ったりします。(他の記事で属性関連や特定タグ専用の関数サンプルを作っています)

ページトップへ

top > javascript研究 > 
タグ文字作成関数

Text

color

font font-size font-size-adjust font-stretch font-weight

letter-spacing

line-height

max-lines

text-decoration-color text-emphasis-color text-indent text-shadow text-size-adjust

vertical-align

word-spacing

Box

background background-color background-image background-position background-size

border border-color border-top-color border-radius border-top-right-radius border-spacing border-top border-width border-top-width

box-shadow

clip

height min-height max-height

margin margin-top

opacity

outline-color outline-offset outline-width

padding padding-top

width min-width max-width

Positioning

top

right

bottom

left

offset-before offset-end offset-after offset-start

visibility

z-index

zoom

Multi-column layout

columns column-count column-gap column-rule column-rule-color column-rule-width column-width

Flexbox

flex flex-grow flex-shrink flex-basis

order

Transforms

perspective

perspective-origin

transform

transform-origin

SVG

fill fill-opacity

flood-color

lighting-color

marker-offset

stop-color stop-opacity

stroke stroke-dasharray stroke-dashoffset stroke-miterlimit stroke-opacity stroke-width

viewport-fill viewport-fill-opacity

カテゴリMENU
お問い合せ