状況の変化に応じて、表示される画像をリアルタイムに変更したい

[新着] Webテンプレートを仮オープンしました



0   名前:  : 2007/04/18(水) 14:28  ID:oAVeEqtD sub-.G
JavaScriptのことは全く分からないのですが、どうしても扱いたい場面が出てきました。
初めての者には複雑な物で、どうしても上手く行かないので質問させていただきます。
助言や具体的な回答をいただけたら幸いです。


■希望
・JvaScriptは外部ファイルで用意して読み込むつもりです。
・なるべく短いソースを希望します。(特に、htmlファイルの方は短くお願いします。)
・なるべく多くの環境で正しく動作することを望みます。


■前提
・【form】の中に【テキストボックス】と【button】がある。
・状況に応じてリアルタイムに【img】の参照アドレスを変更したい。(状況が変化する度に、その状況にあった画像を表示したい)


■条件と画像アドレスの対応
・【テキストボックス】に何も入力されていない状態で【form】が非アクティブ常態のときは[A-1.gif]
・【テキストボックス】に何も入力されていない状態で【form】がアクティブ常態のときは[A-2.gif]
・【テキストボックス】に何も入力されていない状態で【button】にマウスカーソルが乗っているときは【form】のアクティブ非アクティブに係わらず[A-3.gif]
・【テキストボックス】に何か入力された状態で【form】が非アクティブ常態のときは[B-1.gif]
・【テキストボックス】に何か入力された状態で【form】がアクティブ常態のときは[B-2.gif]
・【テキストボックス】に何か入力された状態で【button】にマウスカーソルが乗っているときは【form】のアクティブ非アクティブに係わらず[B-3.gif]


■参考html

<form id="form">
<input tipe="text" valu="" id="textbox" />
<button id="button"><img src="A-1.gif" id="img" /></button>
</form>

関係の無さそうな所は省略しています。

1   名前:  : 2007/04/18(水) 14:28  ID:oAVeEqtD sub-.G
追記です。


[A-3.gif]と[B-3.gif]を表示する条件に

『マウスカーソルが乗っているときは』

とありますが、

『マウスカーソルが乗っているか、またはフォーカスが合っているときは』

と訂正させてください。


改めて宜しくお願い致します。

2   名前:  : 2007/04/18(水) 14:28  ID:oAVeEqtD sub-.G
■参考html
2行目の

『tipe』は『type』の、
『valu』は『value』の間違いです。

3   名前: 匿名 : 2007/04/18(水) 14:28  ID:gHmz5tpF sub-Ds
よくこの板で指摘されていることですが、この掲示板はタイトルにもあ
るように「JavaScript質問板」であって、*丸投げの制作代行サービス*
ではありません。冷たいことを書きますが、

>JavaScriptのことは全く分からないのですが、

という人にはムリです。仮に親切な人がいたとしても、そのコードの
有効性を評価できますか?
しかし、投稿内容から察すると、まったくウェブの知識がないわけで
はないようです(むしろ業者か)。それなら、

>どうしても上手く行かないので

というそのうまくいかない部分を提示してください。

4   名前: 匿名 : 2007/04/18(水) 14:28  ID:FrcKAHu9 sub-Cz
> どうしても上手く行かないので

ならば、現状のコードを見せてもらうのが手っ取り早いんだが。それと『【form】がアクティブ』『【form】が非アクティブ』の意味がよく分からない。



>・【テキストボックス】に何も入力されていない状態で【form】が非アクティブ常態のときは[A-1.gif]
>・【テキストボックス】に何も入力されていない状態で【form】がアクティブ常態のときは[A-2.gif]
>・【テキストボックス】に何か入力された状態で【form】が非アクティブ常態のときは[B-1.gif]
>・【テキストボックス】に何か入力された状態で【form】がアクティブ常態のときは[B-2.gif]

form 要素の「アクティブ状態の変化」イベントをきっかけに、textarea 要素の値の有無を調べ、img 要素の src 属性をセットする。

>・【テキストボックス】に何も入力されていない状態で【button】にマウスカーソルが乗っているときは【form】のアクティブ非アクティブに係わらず[A-3.gif]
>・【テキストボックス】に何か入力された状態で【button】にマウスカーソルが乗っているときは【form】のアクティブ非アクティブに係わらず[B-3.gif]

button 要素における mouseover イベントをきっかけに、textarea 要素の値の有無を調べ、img 要素の src 属性をセットする。

基本的にやるべきことはこれだけ。

# 本格的にやるのであれば、
# http://www-06.ibm.com/jp/developerworks/web/library/wa-finitemach1/
# http://www-06.ibm.com/jp/developerworks/web/library/wa-finitemach2/
# あたりを参考にして状態遷移表でも書いてみると良い。今回の件では必要ないだろうけど。

5   名前: 匿名 : 2007/04/18(水) 14:28  ID:FrcKAHu9 sub-Cz
>>4
訂正:textarea 要素 → input 要素

6   名前:  : 2007/04/18(水) 14:28  ID:eTMWQWZs sub-fY
>>3 匿名(ID:FrcKAHu9)さん

>丸投げの制作代行サービスではありません
はい、そのことは承知しております。
ですので、今回の件を解決する助言やヒント、JavaScriptをどう学んだら良いかのヒントなどを教えていただければそれだけでもとても嬉しいです。
私はまだ、右も左もよく分からないのでとても困っています。

>そのコードの有効性を評価できますか?
確かに、今の私にはそれは無理です。
しかし、もし例となるコードを提示してくださる方がいらっしゃいましたら、時間がかかっても使用前にきちんと解読するつもりです。(そういうのは好きなんです)

>まったくウェブの知識がないわけではないようです(むしろ業者か)
はい、とても小規模ですが、趣味のwebサイトを持っています。
業者と言うのが何を指しているのかはわかりませんが。


>>4-5 匿名(ID:FrcKAHu9)さん

>『【form】がアクティブ』『【form】が非アクティブ』の意味がよく分からない
エンターキーを押すと、その<form>に含まれる最初のsubmitボタンが押される常態を『【form】がアクティブ』と表現しました。
これをJavaScriptで判別することは可能でしょうか。

ヒントを提示していただいて大変有難う御座います。
JavaScriptを少しずつ学んでいけば、いつかはできそうな希望が持てました。

7   名前:  : 2007/04/18(水) 14:28  ID:eTMWQWZs sub-fY
>>3の方のIDはgHmz5tpFでした。
お詫びして訂正申し上げます。

8   名前:  : 2007/04/18(水) 14:28  ID:eTMWQWZs sub-fY
本当に、何度もすみません。
もう1度だけ訂正させてください。
うっかり入れ替えてしまいました。

『お詫びして訂正申し上げます。』

『訂正してお詫び申し上げます。』

9   名前: 匿名 : 2007/04/18(水) 14:28  ID:WHM3QXUe sub-Cz
// DOM Level 2 準拠(Firefox、Opera、Safari)
if (document.implementation &&
    document.implementation.hasFeature ('HTML'       , '2.0') &&
    document.implementation.hasFeature ('HTMLEvents' , '2.0') &&
    document.implementation.hasFeature ('MouseEvents', '2.0'))
{
    var input  = document.getElementById ('textbox');
    var form   = input.form;
    var img    = document.getElementById ('img');
    var button = img.parentNode;
    
    form.addEventListener ('submit', function (event) {
            img.src = (input.value == '') ? 'A-2.gif' : 'B-2.gif';
        }, false);
    
    button.addEventListener ('mouseover', function (event) {
            img.src = (input.value == '') ? 'A-3.gif' : 'B-3.gif';
        }, false);
    
    button.addEventListener ('mouseout', function (event) {
            img.src = (input.value == '') ? 'A-1.gif' : 'B-1.gif';
        }, false);
}

// IE 5.5 以上
else if (/*@cc_on @if (@_jscript_version >= 5.5) true @else@*/ false /*@end@*/)
{
    var input  = document.getElementById ('textbox');
    var form   = input.form;
    var img    = document.getElementById ('img');
    var button = img.parentNode;
    
    form.attachEvent ('submit', function (event) {
            img.src = (input.value == '') ? 'A-2.gif' : 'B-2.gif';
        } );
    
    button.attachEvent ('mouseover', function (event) {
            img.src = (input.value == '') ? 'A-3.gif' : 'B-3.gif';
        } );
    
    button.attachEvent ('mouseout', function (event) {
            img.src = (input.value == '') ? 'A-1.gif' : 'B-1.gif';
        } );

}

NN4.x 以下、WinIE5.0 以下、MacIE5.x 以下は考慮していない。趣味レベルで古い書き方を覚えても仕方ないだろうから(まあ、古いのを覚えるのが趣味、というのはアリかもしれない)。

また、これはあくまで例示であり、実際にこんな書き方はしない。私としてもなるべくエレガントで短いコードを書きたいとは思うのだが、たかだか 100 行にも満たない規模で、必要なことを全て盛り込んだ『なるべく短いソース』なんてのは、土台無理な話だ。

10   名前:  : 2007/04/18(水) 14:28  ID:m6OyVD5v sub-fY
>>9 匿名(ID:WHM3QXUe)さん
私としてもなるべくエレガントで短いコードを書きたいとは思うのだが、たかだか 100 行にも満たない規模で、必要なことを全て盛り込んだ『なるべく短いソース』なんてのは、土台無理な話だ。
すみません、『なるべく短いコード』というのは、「できるなら」という希望であって、軽い気持ちでした。
どうも、少々長くなってもそんなに大きな問題は無いみたいですね。(今回はチャットCGI(配布されているもの)の中で使うこともあって、少し神経質になっていました)


例示してくださいましたコード、私の求める物とは少し違うようでしたが、JavaScriptの知識を得るに当たり、また、実際のコードを書く際に、とても参考になりました。
有難う御座います。

例えば「IEは、addEventListener(というよりDOM Level 2)に対応していないが、代わりにaddEventListenerとほとんど同じように扱える独自のattachEventがあるため、それを利用する」など、色々勉強になりましたし、コードを書く際には、演算子の条件式「?:」など、例示してくださったコードが無ければ使い方が分からず使おうともしなかったと思います。

11   名前:  : 2007/04/18(水) 14:28  ID:m6OyVD5v sub-fY
しらみつぶしに全てのパターンを考えてみました。
かなり頑張ったので、間違いがあれば指摘をください。お願いします。


■サンプルhtml
<form id="FORM" class="SERECT_0">
 <input type="text" value="" id="TEXTBOX" />
 <button type="submit" id="SUBMIT"><img src="A-1.gif" id="IMG1" /></button>
 <button type="reset" id="RESET"><img src="1.png" id="IMG2" /></button>
</form>

htmlを少し変更しました。


■各画像の表示される条件(拡張子 .gif を省略してあります)
[A-1] : 【テキストボックス】に何も入力されていない状態で【FORM】が非アクティブ常態のとき
[B-1] : 【テキストボックス】に何か入力された状態で【FORM】が非アクティブ常態のとき
[A-2] : 【テキストボックス】に何も入力されていない状態で【FORM】がアクティブ常態のとき
    ただし、【IMG2】のsrcが[2.png]のときは、[A-1]となる
[B-2] : 【テキストボックス】に何か入力された状態で【FORM】がアクティブ常態のとき
    ただし、【IMG2】のsrcが[2.png]のときは、[B-1]となる
[A-3] : 【テキストボックス】に何も入力されていない状態で【SUBMIT】にマウスカーソルが乗っているとき
    【FORM】のアクティブ非アクティブは関係無い
[B-3] : 【テキストボックス】に何か入力された状態で【SUBMIT】にマウスカーソルが乗っているとき
    【FORM】のアクティブ非アクティブは関係無い

条件も少し変更しました。


■条件判断の基本など

・当てはまる条件が無い場合は、何もしない
・【IMG2.src】が[2.png]である場合、[A-3]と[B-3]になることは無い。
・フォーカスとマウスポインター両方指定するとややこしいのでフォーカスはあきらめる。ブラウザは完璧に区別できてるのに…。
・AとBは【FORM】を全て【TEXTBOX】に変更するかもしれない。(その場合、htmlもそれに合わせる)
・文字列を表すクォーテーション " ' と、gif画像ファイルの拡張子 .gif は省略してある。


■表の見方
連番 発生イベント
  ├→[【IMG1.src】に書き出す文字列a] この値aを書き出す条件 (この条件aにより【IMG1.src】の値がこの値aに書き換えられる場合、直前の値として可能性のあるもの)
  └→[【IMG1.src】に書き出す文字列i] この値iを書き出す条件 (この条件iにより【IMG1.src】の値がこの値iに書き換えられる場合、直前の値として可能性のあるもの)

※ [他*] : 上記で表示される条件を定義した画像を【IMG1.src】に書き出す以外に行う処理


■条件判断一覧表
A 【FORM】(子孫を含む)が選択状態になった focus
  ├→[A-1] 【IMG2.src】が[2.png]になっていて尚且つ【TEXTBOX.value】が空である場合 ([A-1])
  └→[B-1] 【IMG2.src】が[2.png]になっていて尚且つ【TEXTBOX.value】が空でない場合 ([B-1])
  ├→[A-2] 【IMG2.src】が[2.png]になっておらず且つ【TEXTBOX.value】が空であり且つ【IMG1.src】が[A-3]でない場合 ([A-1])
  └→[B-2] 【IMG2.src】が[2.png]になっておらず且つ【TEXTBOX.value】が空でなく且つ【IMG1.src】が[B-3]でない場合 ([B-1])
  ├→[A-3] このイベントにより[A-3]になることは無い(すでになっていることはあるが、特に分岐の必要は無い)
  └→[B-3] このイベントにより[B-3]になることは無い(すでになっていることはあるが、特に分岐の必要は無い)
  └→[他1] 【FORM.className】を[SERECT_1]にする


B 【FORM】の選択状態が解除された blur
  ├→[A-1] 【TEXTBOX.value】が空であり、【IMG.src】が[A-3]でない場合 ([A-1],[A-2])
  └→[B-1] 【TEXTBOX.value】が空でなく、【IMG.src】が[B-3]でない場合 ([B-1],[B-2])
  ├→[A-2] このイベントにより[A-2]になることは無い
  └→[B-2] このイベントにより[b-2]になることは無い
  ├→[A-3] このイベントにより[A-3]になることは無い(すでになっていることはあるが、特に分岐の必要は無い)
  └→[B-3] このイベントにより[B-3]になることは無い(すでになっていることはあるが、特に分岐の必要は無い)
  └→[他1] 【FORM.className】を[SERECT_0]にする

C 【RESET】にマウスカーソルが乗った mouseover
  ├→[A-1] 【TEXTBOX.value】が空である場合 ([A-1],[A-2])
  └→[B-1] 【TEXTBOX.value】が空でない場合 ([B-1],[B-2])
  ├→[A-2] このイベントにより[A-2]になることは無い
  └→[B-2] このイベントにより[B-2]になることは無い
  ├→[A-3] このイベントにより[A-3]になることは無い
  └→[B-3] このイベントにより[B-3]になることは無い
  └→[他1] 【IMG2.src】を[2.png]にする

D 【RESET】にフォーカスが合わされた
  今のところ考慮せず

E 【RESET】からマウスカーソルが離れた mouseout
  ├→[A-1] 【FORM.className】が[SERECT_1]でなく且つ【TEXTBOX.value】が空である場合 ([A-1],[A-2])
  └→[B-1] 【FORM.className】が[SERECT_1]でなく且つ【TEXTBOX.value】が空でない場合 ([B-1],[B-2])
  ├→[A-2] 【FORM.className】が[SERECT_1]であり且つ【TEXTBOX.value】が空である場合 ([A-1],[A-2])
  └→[B-2] 【FORM.className】が[SERECT_1]であり且つ【TEXTBOX.value】が空でない場合 ([B-1],[B-2])
  ├→[A-3] このイベントにより[A-3]になることは無い
  └→[B-3] このイベントにより[B-3]になることは無い
  └→[他1] 【IMG2.src】を[1.png]にする

F 【RESET】からフォーカスが離れた
  今のところ考慮せず

G 【SUBMIT】にマウスカーソルが乗った mouseover
  ├→[A-1] このイベントにより[A-1]になることは無い
  └→[B-1] このイベントにより[B-1]になることは無い
  ├→[A-2] このイベントにより[A-2]になることは無い
  └→[B-2] このイベントにより[B-2]になることは無い
  ├→[A-3] 【TEXTBOX.value】が空である場合
  └→[B-3] 【TEXTBOX.value】が空でない場合

H 【SUBMIT】にフォーカスが合わされた
  今のところ考慮せず

I 【SUBMIT】からマウスカーソルが離れた mouseout
  ├→[A-1] 【FORM.className】が[SERECT_1]でなく且つ【TEXTBOX.value】が空である場合 ([A-3])
  └→[B-1] 【FORM.className】が[SERECT_1]でなく且つ【TEXTBOX.value】が空でない場合 ([B-3])
  ├→[A-2] 【FORM.className】が[SERECT_1]であり且つ【TEXTBOX.value】が空である場合 ([A-3])
  └→[B-2] 【FORM.className】が[SERECT_1]であり且つ【TEXTBOX.value】が空でない場合 ([B-3])
  ├→[A-3] このイベントにより[A-3]になることは無い
  └→[B-3] このイベントにより[B-3]になることは無い

J 【SUBMIT】からフォーカスが離れた
  今のところ考慮せず

K 【TEXTBOX】の内容が変更された change
  ├→[A-1] 【IMG2.src】が[2.png]であり、【TEXTBOX】が空でない場合 ([B-1])
  └→[B-1] 【IMG2.src】が[2.png]であり、【TEXTBOX】が空である場合 ([A-1])
  ├→[A-2] 【TEXTBOX.value】が空であり、【IMG1.src】が[B-2]である場合 ([B-2])
  └→[B-2] 【TEXTBOX.value】が空でなく、【IMG1.src】が[A-2]である場合 ([A-2])
  ├→[A-3] 【TEXTBOX.value】が空であり、【IMG1.src】が[B-3](か[A-3])である場合 ([B-3])
  └→[B-3] 【TEXTBOX.value】が空でなく、【IMG1.src】が[A-3](か[A-3])である場合 ([A-3])
//ボツ├→[A-3] このイベントにより[A-3]になることは無い
//ボツ└→[B-3] このイベントにより[B-3]になることは無い
//ボツ├→[他1] 【TEXTBOX.value】が空であり、【IMG1.src】が[B-3]または[B-3_k]であるときは、[A-3]と同じ内容で名前の違う[A-3_k]に書き換える
//ボツ└→[他2] 【TEXTBOX.value】が空でなく、【IMG1.src】が[A-3]または[A-3_k]であるときは、[B-3]と同じ内容で名前の違う[B-3_k]に書き換える

12   名前:  : 2007/04/18(水) 14:28  ID:m6OyVD5v sub-fY
調べるなどして、少しずつJavaScriptについて分かってきたので、上記の表を参考に自分でコードを書いてみました。
まさか初作品(?)がこんなに長く複雑な物になるとは思いませんでした。
複雑なのは、コード自体ではなく条件判断全てのパターンをしらみつぶしに考えると言う下準備の方でありますが。


■sample.html
<html><head>
 <script type="text/JavaScript" src="sample.js"></script>
 <style type="text/css"><!-- .SERECT_1{background:gray;} --></style>
</head><body>
 <form id="FORM" class="SERECT_0">
  <input type="text" value="" id="TEXTBOX" />
  <button type="submit" id="SUBMIT"><img src="A-1.gif" id="IMG1" /></button>
  <button type="reset" id="RESET"><img src="1.png" id="IMG2" /></button>
 </form>
</body></html>


■sample.js

製作中のメモなどもそのまま残してあります。
 //(IMG2.src=='2.png')とした場合、IMG2のsrcに'2.png'が入っていてもfalseしか返ってこない。
 //TEXTBOXのvalueは正しく参照できるのに… 仕方が無いのでaltを使ってみたら、うまくいった。でも画像を入れ替えるたびにaltも書き換えないといけない。

 //AとBは、FORMへ指定しても動作しなかったのでとりあえずTEXTBOXへ指定。

 //onchangeはテキスト入力時ではなく書く定時にしか働かないらしい。でもこれは絶対にあきらめられない。同じ機能をgooかどっかで見たことがあるから、できるはず。
 //keyupが候補か?
 //やった!できた!!!

 //Kで(IMG1.src=='B-3.gif'||IMG1.src=='A-3.gif')というふうに[A-3]と[B-3]を両方通してあるのは、素早くキーを押された場合にも正しい結果を返すため。(altも同じように指定しないと予期しない結果になる可能性有り)
 //常に全ての状況から判断してるわけではなく、ぶつ切りで別々に処理し、他の処理が残した痕跡を頼りに状況判断するため、どこか間違いがあると全体に影響を与える。

window.onload = function()
{[/span]//ローカル変数を定義[/span]
 var FORM    = document.getElementById ('FORM');
 var TEXTBOX = document.getElementById ('TEXTBOX');
 var SUBMIT  = document.getElementById ('SUBMIT');
 var RESET   = document.getElementById ('RESET');
 var IMG1    = document.getElementById ('IMG1');
 var IMG2    = document.getElementById ('IMG2');

 //A 【FORM】(子孫を含む)が選択状態になった
 TEXTBOX.onfocus = function () {FORM.className='SERECT_1';
  if      (IMG2.alt=='2')                         {IMG1.src = (TEXTBOX.value=='')?'A-1.gif':'B-1.gif'; IMG1.alt = (TEXTBOX.value=='')?'A-1':'B-1';}
  else if ((TEXTBOX.value=='')&&(IMG1.alt!='A-3')){IMG1.src = 'A-2.gif'; IMG1.alt = 'A-2';}
  else if ((TEXTBOX.value!='')&&(IMG1.alt!='B-3')){IMG1.src = 'B-2.gif'; IMG1.alt = 'B-2';}}

 //B 【FORM】の選択状態が解除された
 TEXTBOX.onblur = function () {FORM.className='SERECT_0';
  if      ((TEXTBOX.value=='')&&(IMG1.alt!='A-3')){IMG1.src = 'A-1.gif'; IMG1.alt = 'A-1';}
  else if ((TEXTBOX.value!='')&&(IMG1.alt!='B-3')){IMG1.src = 'B-1.gif'; IMG1.alt = 'B-1';}}

 //C 【RESET】にマウスカーソルが乗った
 RESET.onmouseover = function () {{IMG2.src='2.png'; IMG2.alt='2';}
  if      (TEXTBOX.value=='')                     {IMG1.src = 'A-1.gif'; IMG1.alt = 'A-1';}
  else if (TEXTBOX.value!='')                     {IMG1.src = 'B-1.gif'; IMG1.alt = 'B-1';}}

 //D 【RESET】にフォーカスが合わされた(今のところ考慮せず)

 //E 【RESET】からマウスカーソルが離れた
 RESET.onmouseout = function () {{IMG2.src='1.png';IMG2.alt='1';}
  if      (FORM.className!='SERECT_1')            {IMG1.src = (TEXTBOX.value=='')?'A-1.gif':'B-1.gif'; IMG1.alt = (TEXTBOX.value=='')?'A-1':'B-1';}
  else                                            {IMG1.src = (TEXTBOX.value=='')?'A-2.gif':'B-2.gif'; IMG1.alt = (TEXTBOX.value=='')?'A-2':'B-2';}}

 //F 【RESET】からフォーカスが離れた(今のところ考慮せず)

 //G 【SUBMIT】にマウスカーソルが乗った
 SUBMIT.onmouseover = function () {{IMG1.src = (TEXTBOX.value=='')?'A-3.gif':'B-3.gif'; IMG1.alt = (TEXTBOX.value=='')?'A-3':'B-3';}}

 //H 【SUBMIT】にフォーカスが合わされた(今のところ考慮せず)

 //I 【SUBMIT】からマウスカーソルが離れた
 SUBMIT.onmouseout = function () {
  if      (FORM.className!='SERECT_1')            {IMG1.src = (TEXTBOX.value=='')?'A-1.gif':'B-1.gif'; IMG1.alt = (TEXTBOX.value=='')?'A-1':'B-1';}
  else                                            {IMG1.src = (TEXTBOX.value=='')?'A-2.gif':'B-2.gif'; IMG1.alt = (TEXTBOX.value=='')?'A-2':'B-2';}}

 //J 【SUBMIT】からフォーカスが離れた(今のところ考慮せず)

 //K 【TEXTBOX】の内容が変更された
 TEXTBOX.onkeyup = function () {
  if      (IMG2.alt=='2')                         {IMG1.src = (TEXTBOX.value=='')?'A-1.gif':'B-1.gif'; IMG1.alt = (TEXTBOX.value=='')?'A-1':'B-1';}
  else if (TEXTBOX.value=='')                     {IMG1.src = (IMG1.alt=='B-3'||IMG1.alt=='A-3')?'A-3.gif':'A-2.gif'; IMG1.alt = (IMG1.alt=='B-3'||IMG1.alt=='A-3')?'A-3':'A-2';}
  else if (TEXTBOX.value!='')                     {IMG1.src = (IMG1.alt=='A-3'||IMG1.alt=='B-3')?'B-3.gif':'B-2.gif'; IMG1.alt = (IMG1.alt=='A-3'||IMG1.alt=='B-3')?'B-3':'B-2';}}
}

こんなのでどうでしょうか。
何方か評価を下してくださると嬉しいです。(条件の漏れやミスからコードとしての修正点、より良い物にするための追加点、気になった点・助言など何でも嬉しいです)

お隣の【RESET】(ごく単純なロールオーバー画像)と同じくらいの気持ちで設定しようと思い立ったのですが、いざ設定して見ると凄く複雑になってしまいました。
でも、JavaScriptを学ぶ良い機会になり良かったです。

13   名前:  : 2007/04/18(水) 14:28  ID:m6OyVD5v sub-fY
弱調タグの開始タグが1箇所終了タグになってしまいました。
『書く定時』は『確定時』の変換ミスですね。

14   名前:  : 2007/04/18(水) 14:28  ID:m6OyVD5v sub-fY
本当に修正してばかりですが、

『Kで(IMG1.src=='B-3.gif'||IMG1.src=='A-3.gif')というふうに[A-3]と[B-3]を両方通してあるのは』

の src は alt 、 3.gif は 3 の間違いです。


修正機能が欲しいです。

15   名前: 匿名 : 2007/04/18(水) 14:28  ID:nMg0Pmaj sub-Cz
グッジョブ!マジでグッジョブ!

> まさか初作品(?)がこんなに長く複雑な物になるとは思いませんでした。

作れるものより、作りたいものを作るのが、意外に近道だと思う。と言うか、COBOL か何かの経験者でしょうか。



* HTML に関して

率直に言うと、>>12 は HTML でも XHTML でもなく、名前空間を持たない何かの XML ドキュメントだ。試しにファイル拡張子を .xhtml にして Firefox に読み込ませてみれば、XHTML とは認識しないはず。

何でこんなうるさいことを言うかというと、XML をスクリプトから扱うには、HTML と同じ書き方では駄目だから。(X)HTML の文法にはもっと敏感になろう。何が必須で何が省略可か、デフォルト値は何か、ということが(そして、XHTML の場合は名前空間が)今後極めて重要になる。

# まあ、実用上は昔ながらの HTML 用の書き方で十分だと思うけど。IE が XHTML に対応していない以上、もうしばらくは XHTML でも HTML として扱われることになるだろうし。



* JavaScript に関して

・『【FORM】のアクティブ』というのは、どうやら『【テキストボックス】のフォーカス』のことかな。一応、DOMActivate というイベント型も存在するので、念のため。

・『(IMG2.src=='2.png')とした場合……falseしか返ってこない』← 慣習的に、img.src は絶対 URI を返す。だからファイル名だけでは一致しない。

・if 文と三項演算子(?..:)を混ぜて使うと、分かりづらくてバグのもと。何度も同じ条件を書くなら、if 文でまとめてしまった方が良い。


それと……書くべきか迷ったけど、一応書いておく。>>12 は、FORM、TEXTBOX などをローカル変数で保持しているよね。普通なら全く異論はないのだけど、今回のケースに限り、IE6 および Firefox 1.5 でメモリリークが発生する。だから、涙を堪えて、これらをグローバル変数にしておこう。

# IE7、Firefox 2.0 で修正されているのだけど、IE6 が消え去るまでは……ね。


いやしかし、これはマジでグッジョブです。

16   名前: 匿名 : 2007/04/18(水) 14:28  ID:gaVmwAE3 sub-Cz
# ID がコロコロ変わるな……まあ良いか。

触発されて書いてみる。IE5.5+、Gecko1.x+、Opera8.0+、Safari2.0+。条件の見落としは多分にあると思う。
/*@cc_on@*/

if (document.implementation &&
/*@if (@_jscript_version > 5.5) @else@*/
    document.implementation.hasFeature ('HTML'       , '2.0') &&
    document.implementation.hasFeature ('HTMLEvents' , '2.0') &&
    document.implementation.hasFeature ('MouseEvents', '2.0') &&
/*@end@*/
    true)

/*@if (@_jscript) attachEvent ('on' + @else@*/
addEventListener (/*@end@*/ 'load', function (event) {
    var sourceData = {
        // 使用するノードにラベルを張っておく
        form    : document.getElementById ('FORM'),
        textbox : document.getElementById ('TEXTBOX'),
        submit  : document.getElementById ('SUBMIT'),
        reset   : document.getElementById ('RESET'),
        image1  : document.getElementById ('IMG1'),
        image2  : document.getElementById ('IMG2'),
        
        getState : function () {
            return (this.textbox.value == '') ? 'blank' : 'non-blank';
        },
        
        observeEvent : function (targetLabel, eventType) {
            var listener = function (event) {
                arguments.callee.prototype.handleEvent (event);
            };
            listener.prototype = {
                sourceData  : this,
                targetLabel : targetLabel,
                eventType   : eventType,
                handleEvent : function (event) {
                    var data  = this.sourceData;
                    var action = data.actions[ data.getState () ];
                    if (action) {
                        var listener = action[ this.targetLabel ];
                        if (listener) {
                            var handler = listener[ this.eventType ];
                            if (handler) {
                                handler.call (data, event);
                            }
                        }
                    }
                }
            };
            this[targetLabel]./*@if (@_jscript) attachEvent ('on' + @else@*/
                              addEventListener (/*@end@*/ eventType, listener, false);
            listener = targetLabel = eventType = null;
        },
        
        actions : {
            'blank' : {   // テキストボックスに入力値がない場合
                'reset' : {
                    'mouseover' : function (event) {
                        this.image1.src = 'A-1.gif';
                        this.image2.src = '2.png';
                    },
                    'mouseout' : function (event) {
                        this.image1.src = (this.form.className != 'SECRET_1') ? 'A-1.gif' : 'A-2.gif';
                        this.image2.src = '1.png';
                    }
                },
                'submit' : {
                    'mouseover' : function (event) {
                        this.image1.src = 'A-1.gif';
                        this.image2.src = '1.gif';
                    },
                    'mouseout' : function (event) {
                        this.image1.src = (this.form.className != 'SECRET_1') ? 'A-1.gif' : 'A-2.gif';
                    }
                },
                'textbox' : {
                    'focus' : function (event) {
                        this.image1.src = (  this.image2.src.match (/2\.gif/))   ? 'A-1.gif' :
                                          (! this.image2.src.match (/A-3\.gif/)) ? 'A-2.gif' :
                                          this.image1.src;
                    },
                    'blur' : function (event) {
                        this.form.className = 'SECRET_0';
                        this.image1.src = (! this.image2.src.match (/A-3\.gif/)) ? 'A-1.gif' :
                                          this.image1.src;
                    },
                    'keyup' : function (event) {
                        this.image1.src = (this.image2.src.match (/2\.gif/))      ? 'A-1.gif' :
                                          (this.image1.src.match (/[AB]-3\.gif/)) ? 'A-3.gif' :
                                          'A-2.gif';
                    }
                }
            },
            'non-blank' : {   // テキストボックスに入力値がある場合
                'reset' : {
                    'mouseover' : function (event) {
                        this.image1.src = 'B-1.gif';
                        this.image2.src = '1.gif';
                    },
                    'mouseout' : function (event) {
                        this.image1.src = (this.form.className != 'SECRET_1') ? 'B-1.gif' : 'B-2.gif';
                        this.image2.src = '1.gif';
                    }
                },
                'submit' : {
                    'mouseover' : function (event) {
                        this.image1.src = 'A-3.gif';
                    },
                    'mouseout' : function (event) {
                        this.image1.src = (this.form.className != 'SECRET_1') ? 'B-1.gif' : 'B-2.gif';
                    }
                },
                'textbox' : {
                    'focus' : function (event) {
                        this.image1.src = (  this.image2.src.match (/2\.gif/))   ? 'B-1.gif' :
                                          (! this.image2.src.match (/B-3\.gif/)) ? 'B-2.gif' :
                                          this.image1.src;
                    },
                    'blur' : function (event) {
                        this.form.className = 'SECRET_0';
                        this.image1.src = (! this.image1.src.match (/B-3\.gif/)) ? 'B-1.gif' :
                                          this.image1.src;
                    },
                    'keyup' : function (event) {
                        this.image1.src = (this.image2.src.match (/2\.gif/))      ? 'B-1.gif' :
                                          (this.image1.src.match (/[AB]-3\.gif/)) ? 'B-3.gif' :
                                          'B-2.gif';
                    }
                }
            }
        }
    };
    
    sourceData.observeEvent ('textbox', 'focus'    );
    sourceData.observeEvent ('textbox', 'blur'     );
    sourceData.observeEvent ('textbox', 'keyup'    );
    sourceData.observeEvent ('reset'  , 'mouseover');
    sourceData.observeEvent ('reset'  , 'mouseout' );
    sourceData.observeEvent ('submit' , 'mouseover');
    sourceData.observeEvent ('submit' , 'mouseout' );
    
    sourceData = null;
    
    /*@if (@_jscript) detachEvent ('on' + @else@*/
    removeEventListener (/*@end@*/ 'load', arguments.callee, false);
}, false);

一覧へ戻る