まほ〜のあいらんどけんきゅ〜

JavaScriptによる掲示板改造(その1)

1.まずは準備編

改造にはWindowsならメモ帳(Notepad)で十分です。 スタートメニュー→「すべてのプログラム」→「アクセサリ」→「メモ帳」で選択します。 1回呼び出すとWindowsXPの場合、最近使ったソフトがスタートメニューを選んだだけで表示されるので、 そこからデスクトップにドラッグしてショートカットも作っておきましょう。 そして、メモ帳の「メニューバーの表示」→「ステータスバー」をクリックしておくと、下にステータスバーが表示され、 カーソルのある位置が何行、何列というふうに表示されます。 これは、デバッグに役立つのでぜひ表示させるようにしておいてください。 次に既に書き込みが5件以上あるような掲示板を表示させ、そのソースをメモ帳で表示します。 これは、右クリックで「ソースの表示」を選んでもいいですし、メニューバーの「表示」から「ソース」を選んでもいいです。 そして、そのソースの画面のメニューバーの「ファイル」→「名前をつけて保存」を選択し、自分の使いやすいフォルダに保存します。 このとき、「ファイルの種類」は「すべてのファイル」を選択し、拡張子は.htmlを付けて保存します。 そして、保存したファイルを右クリックして「プログラムから開く」→「Notepad」を選択して開きます。 そして、実際に外部ファイルの呼び出しタグを書き込む位置(<center><b></b></center>の間)に<script>と書き、2回エンターを押して改行して </script>と書きます。 このスクリプトタグの間にソースを書いていきます。 保存したファイルをダブルクリックしてInternet Explorerなどのブラウザで表示させ、動作確認します。 作業中は、メモ帳で開いたウィンドウとInternet Explorerなどのブラウザのウィンドウの両方を開いておき、 メモ帳のソースを直したら、メニューバーのファイル→「上書き保存」を選択して保存し、 ブラウザの方で更新をクリックして確認するという繰り返しになります。

スクリプトが完成したら、先ほどの<script></script> の間にあるソースをコピーペーストして、別ウィンドウで開いたメモ帳に貼り付け、名前を付けて保存します。 このとき、すぐにアップロードしないのなら、開きやすいように拡張子は.txtのままでもいいですし、 アップロードするのであれば、拡張子は普通のサーバーに上げる場合は.js、 iらんどの画像倉庫に上げる場合は.gif.png.bmpにしておきます。 ブラウザのエラー表示の設定ですが、エラーをいちいち表示する設定にする必要はありません。 いちいち通知しない設定の場合でも、ステータスバーの左側に黄色い三角のエラーマークが表示されます。 この三角をダブルクリックすると、エラーの内容が表示されます。 詳細が隠れている場合は、詳細をクリックして確認すると、何行目の何文字目にエラーがあるか表示されたりする (実際に位置どおりに表示されるとは限らないようです)ので、それを参考に直します。 どちらかというと、Netscapeの方がピンポイントでエラーを通知してくれるのでお勧めです。 Netscapeで確認するときは、メニューバーの「ファイル」→「ファイルを開く」で保存してあるフォルダから選択して表示させます。 そして、メニューバーの「ツール」→「Web開発」→「JavaScript コンソール」を選択すると、エラー内容が表示されます。

もう1つデバッグに役立つのが、alertによる警告ウィンドウです。 スクリプトソースの途中の行に

alert('ここまでOK');

と書くと、そこまでの行にエラーが無ければ警告ウィンドウが表示されます。 もちろん複数記述して

alert('3行目までOK');

とかしてもいいですし、()の中に変数名を入れれば変数の中身をチェックすることもできます。 aという変数の中身を見たいときは

alert(a);

という感じです。 配列の入った変数名であれば、配列の中身を見ることもできます。

2.次に基本編

まずは、俗に言うところのタグの流し込みというやつからです。 JavaScriptの基本的な構文の

document.write();

でテキスト、HTML、CSS、JavaScriptを流し込むことができます。 例えば、CSSを流し込む場合は、

document.write('<style><!--body{margin:0px;padding10px;color:white;background-color:black}--></style>');

といった感じになります。 書き出す内容が文字列の場合は、シングルクォーティション(')か ダブルクォーティション(")で文字列を挟みます。 なお、HTMLもCSSも文字列として書き出すことに注意してください。 属性の値などでこれらのクォーティションを使う場合は、 シングルクォーティションの中に更に入れ子にしてシングルクォーティションを入れたり、 ダブルクォーティションの中に更に入れ子にしてダブルクォーティションを入れることはできません。 シングルクォーティションの中にダブルクォーティションを入れたり、 ダブルクォーティションの中にシングルクォーティションを入れることはできるので、 例えば

document.write('<div align="center">');

と書くようにします。 更に入れ子にしたい場合や、単独でクォーティション記号を書き出したい場合には、直前にエスケープ記号(\)をつけて、

document.write('クオーティションには\'と\"があります。');

のようにします。 このエスケープ記号を用いることによって、記号を単なる文字として扱うことができます。 なお、document.writeで書き出す文字列の途中で改行してはいけません。

たくさん流し込むときは、以下のような方法を使います。いずれの場合も、実際には1行に続けて書き出されます。

  1. 以下のように何回かに分けて書き出す。
    
    document.write('〜');
    document.write('〜');
    document.write('〜');
    
  2. カンマ(,)で区切って記述する。 (documentオブジェクトにおけるwriteメソッドの引数を複数持たせていると考える。)
    
    document.write(	'〜',
    		'〜',
    		'〜');
    
  3. +記号で区切って記述する。(文字列を連結する演算子+を使う。)
    
    document.write(	'〜'+
    		'〜'+
    		'〜');
    
  4. 変数に代入演算子で加えていき、最後にその変数を書き出す。 (変数をwriteメソッドの引数にするときは、クォーティションは書かない。)
    
    var a='〜';
    a+='〜';
    a+='〜';
    document.write(a);
    

変数はいろいろな値や文字列などを格納する箱のようなものです。 a+=は変数aの中身に右辺の値を加えたものを代入するということです。 1.〜4.のどの方法を用いてもいいのですが、特定のブラウザにしか読み込ませたくないHTMLやCSSがある場合なども考えると、 1.か4.の方法がお勧めです。

例えば、途中にif文などでブラウザ判別することにより、 {}でくくった部分を一部のブラウザにだけ書き出すことができます。

例:IE4以上限定の場合


if(document.all){
			a+='〜';}

3.リンクテキストの入れ替え

リンクのテキストを入れ替えるためには、linkオブジェクトを操作しなければなりません。 スクリプトタグが挿入される位置は比較的上のほうですから、普通にテキストを入れ替える命令文を書いただけでは、 その記述の上にあるリンクしか操作することができません。 そこでonloadというイベントハンドラを使うことになります。 bodyタグを書き出してonloadのイベントハンドラを付けてもいけそうですが、 ここではタグの重複を避けてwindow.onloadで処理を呼び出すことにします。

window.onload=function(){ここに処理を記述}

という感じです。 windowオブジェクトが読み込まれたら、関数内の処理を実行するという意味です。 関数名は特に付ける必要はありません。 関数をオブジェクトとして使用したり、別の場所で関数を呼び出したりするわけではないので、 関数名を記述せずにいきなりwindow.onload=function(){の後に記述できるわけです。 もちろん関数を別に定義してイベントハンドラで別に呼び出しても構いませんが、上記のようにした方が簡潔です。 onloadonLoadと書くこともありますが、 onloadと書いた方がより多くのブラウザで動作するようです。

3-1.IE&Opera編

まずは、InternetExplorer4.0以上とOperaに対応させる部分のソースです。 といっても現実にはIE5以上とOperaはDOMの標準にかなり対応しているので、ほとんどIE4対策ですが。 ここで使うプロパティはinnerTextinnerHTMLouterHTMLです。 outerTextというものもありますが、ほとんど使い道はないと思います。 これらのプロパティは比較的単純でとても便利です。 IE4以上ではリンクオブジェクトにこれらのプロパティが対応しているので、比較的簡単にリンクテキストの入れ替えができます。

すべてのリンクオブジェクトについて、innerTextの値を参照して、その値の種類によって別のテキストに入れ替えます。 すべてのリンクを参照するためにfor文による繰り返し処理を行います。

for(i=0;i<document.links.length;i++){個々に処理を記述}

が基本の形です。 リンクオブジェクトは配列を形成していて、0からスタートする番号を持っています。 documentの中にあるlinkオブジェクトの数がdocument.links.lengthです。 これをリンクオブジェクトの配列数ともいいます。 iが0からスタートして、リンクオブジェクトの数よりも1つ少ない数に達するまでiに1ずつプラスしていきます。 idocument.links.lengthの数に達したら、 i<document.links.lengthを満たさなくなるので、このfor文を抜けて次の処理に写ります。 i++はiに1を足すという意味です。これをインクリメント演算子といいます。 リンクオブジェクトには0からスタートする番号が付いていて、 最後の番号はdocument.links.lengthよりひとつ少ない数字の番号が付いています。 これらの番号を添え字といいます。 0からスタートなので、1つ少ない数で終わるのがミソです。

if文により、条件分岐して{}内の処理を行います。

if(条件式){条件が正しければ、ここに書いてある処理を行う}

ちなみに値が等しい場合は==を使います。 プロパティに値を代入するときが=です。 そのリンクのテキストの文字が何であるかを判定して、そのテキストに対応する自分で決めた文字を代入して上書きする感じです。 この場合ですと、

if(document.links[i].innerText=="[ケータイMode表示]"){innerText=""}

とすると、「[ケータイMode表示]」の部分が空文字列に入れ替えられて、非表示になります。 もちろん{innerText=""}のところを{innerHTML=""}としても結構ですし、 画像などに入れ替えることを考えるとinnerHTMLの方がメンテナンスしやすいと思います。 ただし、innerTextを使った方がより高速に処理が可能です。(体感的にはそれほどの差ではないとは思いますが) 画像などのHTMLを使ったり、他のタグを挿入したりしない場合には、innerTextでいいでしょう。

先ほどのfor文の中に、このif文を続けて書いていきます。


for(i=0;i<document.links.length;i++){
	if(document.links[i].innerText=="[ケータイMode表示]"){innerText=""}
	else if(document.links[i].innerText=="My HomePage"){innerText="My Website"}
	else if(document.links[i].innerText=="Delete"){innerText="削除"}
}

このように2つ目以降のifの前にはelseを付ける方がお勧めです。 このスクリプトの場合はelseを付けなくても支障はないのですが、 後々いろいろなスクリプトを組むときに支障が出る可能性があります。 if()内が正しければ、その後の{}内の処理が行われますが、 elseが付いていない場合には次のif()内も正しい場合に、 その後の{}内の処理も行われてしまいます。 スクリプトの種類によっては、それでは動作しないようなことも起こりえます。 (処理を行うごとに目印になる変数の値を変えて、その値によって判別する場合など) この場合はinnerTextの値が2種類になることはないので、1つしか満たしませんから不都合がないというわけです。 でも、elseがないと、いちいち最後のif文まで判定しなくてはならないので、 微妙に処理速度も遅くなります。(これも支障がない程度ですが…) プログラムの約束事としてif文の2つ目以降にはelseを付ける癖を付けておきましょう。 (このサイト内にも付いてないのもありますが、徐々に直していきます)

documentオブジェクトのi番目のlinksオブジェクトのinnerTextを参照したり、 書き換えたりするのにドットで区切って記述するわけですが、面倒なので省略することもできます。

with(省略するオブジェクトなど){省略した記述}

というようにwithを使って省略できます。 例えば、下記のような感じです。


for(i=0;i<document.links.length;i++){
	with(document.links[i]){
	if(innerText=="[ケータイMode表示]"){	innerText="";}
	else if(innerText=="My HomePage"){	innerText="My HP";}
	else if(innerText=="Delete"){ 		innerText="Del";}
	else if(innerText=="[1]書く"){		innerText="write";}
	else if(innerText=="[4]私書箱IDで書く"){innerText="ID write";}
	else if(innerText=="[6]ログを表示"){	innerText="Log";}
	else if(innerText=="[0]戻る"){ 		innerHTML="HOME";}
}}

{}がたくさん出てきて混乱しそうですが、 一つ一つの構文で始めの{を書いたら終わりの}も同時に書いておく癖をつけておくといいです。 後はその間に改行を入れてソースを書けばいいわけですから。

以上の部分をIE4以上のブラウザ判別でよく使われる if(document.all){}{}の中に記述します。 そして、Netscape6以上などのDOM標準対応ブラウザ用の部分を else if(document.getElementsByTagName){}の中の{}の中に記述します。

全体として


document.write('〜');
・・・
window.onload=function(){
	if(document.all){IE用の記述}
	else if(document.getElementsByTagName){Netscape6以上用の記述}
}

という感じの構成になります。

3-2.Netscape6以上&Mozilla編

肝心のNetscape6以上用の記述の中身です。 単純に言いますと、IE用の部分の document.links[i]document.getElementsByTagName('a')[i].firstChild に、 innerTextnodeValue にする感じです。

置換後の部分に画像などのHTMLを使う場合は書き方が少し変わるのでwithでの省略が出来ません。 (firstChildwith()の中から抜けば、 document.getElementsByTagName('a')[i]までの省略はできますが…) この場合はdocument.getElementsByTagName('a')[i].innerHTMLとする必要があります。


for(i=0;i<document.links.length;i++){		
	with(document.getElementsByTagName('a')[i].firstChild){	
		if(nodeValue=="My HomePage"){	nodeValue="My HP";}
		else if(nodeValue=="Delete"){	nodeValue="Del";}
		else if(nodeValue=="[1]書く"){	nodeValue="write";}
		else if(nodeValue=="[4]私書箱IDで書く"){	nodeValue="ID write";}
		else if(nodeValue=="[0]戻る"){
			document.getElementsByTagName('a')[i].innerHTML="<font size=+1>HOME</font>";}
}}
この場合でも全部をinnerHTMLにする(その方が簡明ですが、Web標準からは遠ざかります)など、 いろいろな書き方が考えられますね。

document.getElementsByTagName('a')[i]で0から数えてi番目のaタグにアクセスできます。 firstChildで、そのタグの中の最初の子ノードにアクセスする感じです。 この子ノードにはテキストも含まれます。 この場合はひとつしかないので、必然的にaタグの中身が参照されるわけですね。 単にfirstChildだけでは、そのノードの値にまでアクセスできないので、nodeValueとします。

ここまでをまとめると下記のような感じになります。(1例です)


window.onload=function(){
if(document.all){
for(i=0;i<document.links.length;i++){
	with(document.links[i]){
	if(innerText=="[ケータイMode表示]"){	innerText="";}
	else if(innerText=="My HomePage"){	innerText="My HP";}
	else if(innerText=="Delete"){ 		innerText="Del";}
	else if(innerText=="[1]書く"){		innerText="write";}
	else if(innerText=="[4]私書箱IDで書く"){innerText="ID write";}
	else if(innerText=="[6]ログを表示"){	innerText="Log";}
	else if(innerText=="[0]戻る"){ 		innerHTML="<font size=+1>HOME</font>";}
}}}
else if(document.getElementsByTagName){
for(i=0;i<document.links.length;i++){		
	with(document.getElementsByTagName('a')[i].firstChild){
		if(nodeValue=="[ケータイMode表示]"){	nodeValue=""}
		else if(nodeValue=="My HomePage"){	nodeValue="My HP";}
		else if(nodeValue=="Delete"){		nodeValue="Del";}
		else if(nodeValue=="[1]書く"){		nodeValue="write";}
		else if(nodeValue=="[4]私書箱IDで書く"){	nodeValue="ID write";}
		else if(nodeValue=="[6]ログを表示"){		nodeValue="Log";}
		else if(nodeValue=="[0]戻る"){
			document.getElementsByTagName('a')[i].innerHTML="<font size=+1>HOME</font>";}
}}}
}

前半部分のif(document.all){から12行目の}}}までを抜いて、 else if(document.getElementsByTagName)elseを抜くと、IE6でも動作確認可能です。


最後に私が自分のサイトで使っているやつです。(背景画像はわざと抜いてあります。)

ソースサンプル
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送