- ベストアンサー
クリッカブルマップでリモートロールオーバー
過去の質問を見ましたが、ソフトを使ったやり方でしたので、改めて質問させていただきます。 1つの画像の中にクリッカブルマップを3つ貼り、リモートロールオーバーで別の場所にある画像を変更させたいと考えています。 別場所に表示される画像からもリンクができるとうれしいです。 できればjavascriptは別ファイルにしたいのですが、htmlファイルに書き込む形でも構いませんので、方法を教えていただければと思います。 どうぞよろしくお願いいたします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
えぇっと… 下のソースで理解なさったかどうかがこちらではわからないので、一応はじめから説明します。 (プログラムも書き直します) <<1>> 各エリアにマウスがきたらある1つの画像を変更する。 について… [1-1] 変更予定の画像をHTML側に記述します。( id を 'id-img' としておきます ) <img id='id-img' src='最初に表示される画像パス'> [1-2] つぎに、画像を変更するプログラムをSCRIPT側に書いてみる。 その際、変更予定の画像リストを配列として用意しておくと楽だ。 var arrImgs = [ 'images/A.jpg', 'images/B.jpg', ... ]; さらに言うと、Imageオブジェクトにしておくと利用者のコンピュータに画像データが 読み込まれるため画像を変更した際の動作がスムーズに行われる。 そこで、さきほどの var arrImgs = [ 'images/A.jpg', 'images/B.jpg', ... ]; を 次のように書き直すことにする。 var arrImgs = []; // ここでは何も書かない。 arrImgs[0] = new Image(); arrImgs[0].src = 'images/A.jpg'; arrImgs[1] = new Image(); arrImgs[1].src = 'images/B.jpg'; : : という具合だ。 では、画像を変更する関数 Change を書いてく。 function Change ( index ) // index には、画像リストの番号( 0 ~ )が入る { // 1 : 変更する画像 ( img 要素 ) を変数 obj にいったん入れる // これは、id が 'id-img' であるものをひろってこればよい。[1-1] // document.getElementById( id名 ) でひろえる var obj = document.getElementById( 'id-img' ); // 2 : その画像の src に、(画像リストから) index で指定した画像パスを入れる。 // index で指定した画像パスについてだが… // まず、arrImgs[index] とする。これはさきほども言ったがImageオブジェクトだ。 // Imageオブジェクトから画像パスを取得するには、arrImgs[index].src としよう。 // それを obj.src に入れてしまえば画像が入れ替わる obj.src = arrImgs[index].src; } しかし、これだけでは、エリアにマウスをもってきても画像は変わらない。 それは、エリアにイベントをつけていないから。 [1-3] 各エリアにイベントをつけよう。 まず、クリッカブルマップをHTML側に記述する。画像は map.gif。 <img src="images/map.gif" usemap="#ClickableMap1" width="250" height="150"> <map id="ClickableMap1" name="ClickableMap1"> <area shape="rect" coords="20,25,116,64"> <area shape="circle" coords="67,101,25"> <area shape="polygon" coords="178,72,138,132,218,132"> </map> と各エリアを作っていく。area の書式はここでは触れないでおく。 また、map要素には、id と name を両方書いておこう。(同じ名前にして下さい) つぎに、各エリアにイベントをつける。 マウスオーバーなのだから onmouseover を書く。 また、実行する関数は [1-2] で作成した Change 関数だ。 その際、関数の引数には、画像リストの番号を表す 0, 1, 2, ... を入れておく。 ( すると、Change関数の index には、0, 1, 2, ... という番号が入る ) <img src="images/map.gif" usemap="#ClickableMap1" width="250" height="150"> <map id="ClickableMap1" name="ClickableMap1"> <area shape="rect" coords="20,25,116,64" onmouseover="Change(0)"> <area shape="circle" coords="67,101,25" onmouseover="Change(1)"> <area shape="polygon" coords="178,72,138,132,218,132" onmouseover="Change(2)"> </map> ここまでで、次のようなソースになっていると思う。 最初に表示される画像は、A.jpg としといた。 ------------------------------------------------------------------------------------ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang='ja'> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta http-equiv="Content-Style-Type" content="text/css"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <script type='text/javascript'> var arrImgs = []; arrImgs[0] = new Image(); arrImgs[0].src = 'images/A.jpg'; arrImgs[1] = new Image(); arrImgs[1].src = 'images/B.jpg'; arrImgs[2] = new Image(); arrImgs[2].src = 'images/C.jpg'; function Change ( index ) // index には、画像リストの番号( 0 ~ )が入る { var obj = document.getElementById( 'id-img' ); obj.src = arrImgs[index].src; } </script> </head> <body> <img id='id-img' src='images/A.jpg'><br> <img src="images/map.gif" usemap="#ClickableMap1" width="250" height="150"> <map id="ClickableMap1" name="ClickableMap1"> <area shape="rect" coords="20,25,116,64" onmouseover='Change(0)'> <area shape="circle" coords="67,101,25" onmouseover='Change(1)'> <area shape="polygon" coords="178,72,138,132,218,132" onmouseover='Change(2)'> </map> </body> </html> ------------------------------------------------------------------------------------ (全角スペースが使われています。) 下のソースと同じ動きなんだけどだいぶ違う、というか、ものすごく簡単になっていると思う。 (下はものすごくまどろっこしいよね…w) これで <<1>> 各エリアにマウスがきたらある1つの画像を変更する。 は完成だ。 つぎに <<2>> それぞれの画像に対応するリンクを貼る。 を解説します。 (とりあえず、ここまでで投稿しときます)
その他の回答 (4)
- ai10
- ベストアンサー率27% (3/11)
あ…ごめんなさい。 「下のソース」って書いてしまったが、 正しくは、「ANo.1 のソース」ってことです。 申し訳ないです。
- ai10
- ベストアンサー率27% (3/11)
で、ここから先が本題とは関係ない話なわけですが (興味なかったらおもむろにスルーしたって下さいw) HTML側に onmouseover ( や、onload, onclick など ) を書くのはあまりよろしくないので、 できればスクリプト側で onmouseover のイベントを追加したい。 イベントの付け方は、 IEなら element.attachEvent( 'onmouseover', イベント発生時に実行する関数 ) それ以外なら element.addEventListener( 'mouseover', イベント発生時に実行する関数, false ) とすればよい。 だが、いちいち、 if( element.attachEvent ) ... else if( element.addEventListener ) ... としているのは面倒なので //@cc_on element./*@if (@_jscript) attachEvent( 'on'+ @else@*/ addEventListener( /*@end@*/ 'mouseover', 関数, false ) とすれば1行で済む。 ただし、これはイベントをつける要素が既に読み込まれていないと基本的にはダメだ。 なので、'onload' 時にイベントをつけるようにしなければならない。 もちろん、'onload' イベントも attachEvent addEventListener を使う。 ( window.onload は使ってはいけない ) すると、ソースはこうなる。 ※一部省略 ------------------------------------------------------------------------------------ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang='ja'> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta http-equiv="Content-Style-Type" content="text/css"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <script type='text/javascript'> : : //@cc_on // onload window./*@if (@_jscript) attachEvent( 'on'+ @else@*/ addEventListener( /*@end@*/ 'load', function () { var obj; obj = document.getElementById( 'id-area-0' ); obj./*@if (@_jscript) attachEvent( 'on'+ @else@*/ addEventListener( /*@end@*/ 'mouseover, function() { Change( 0 ); }, false ); obj = document.getElementById( 'id-area-1' ); obj./*@if (@_jscript) attachEvent( 'on'+ @else@*/ addEventListener( /*@end@*/ 'mouseover, function() { Change( 1 ); }, false ); obj = document.getElementById( 'id-area-2' ); obj./*@if (@_jscript) attachEvent( 'on'+ @else@*/ addEventListener( /*@end@*/ 'mouseover, function() { Change( 2 ); }, false ); }, false ); : : </script> </head> <body> <a href='http://www.google.co.jp/'><img id='id-img' src='images/A.jpg'></a> <br> <img src="images/map.gif" usemap="#ClickableMap1" width="250" height="150"> <map id="ClickableMap1" name="ClickableMap1"> <area shape="rect" coords="20,25,116,64" id='id-area-0'> <area shape="circle" coords="67,101,25" id='id-area-1'> <area shape="polygon" coords="178,72,138,132,218,132" id='id-area-2'> </map> </body> </html> ------------------------------------------------------------------------------------ (全角スペースが使われています。) しかし、これは、イベントの追加する数が多くなればなるほど面倒だ。 そこで、document の onmouseover だけを監視すればよいというわけだ。 それならイベントをつける要素が読み込まれているかどうかなんて気にする必要もないし、 'onload' も書く必要もない。 ※一部省略 ------------------------------------------------------------------------------------ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang='ja'> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta http-equiv="Content-Style-Type" content="text/css"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <script type='text/javascript'> : : //@cc_on document./*@if (@_jscript) attachEvent( 'on'+ @else@*/ addEventListener( /*@end@*/ 'mouseover', function ( evt ) { var obj = evt.toElement || evt.target; // 要素取得 var ret = obj.id.match( /^id-area-([0-9]+)$/ ); if( ret ) { var idx = ret[1] - 0; Change( idx ); } }, false ); : : </script> </head> <body> <a href='http://www.google.co.jp/'><img id='id-img' src='images/A.jpg'></a> <br> <img src="images/map.gif" usemap="#ClickableMap1" width="250" height="150"> <map id="ClickableMap1" name="ClickableMap1"> <area shape="rect" coords="20,25,116,64" id='id-area-0'> <area shape="circle" coords="67,101,25" id='id-area-1'> <area shape="polygon" coords="178,72,138,132,218,132" id='id-area-2'> </map> </body> </html> ------------------------------------------------------------------------------------ イベントが発生した要素については、 IEなら evt.toElement、それ以外なら evt.target で取得できる。 var obj = evt./*@if (@_jscript) toElement @else@*/ target /*@end@*/; でもいい。 しかし、この時点では何の要素なのかがわからない。もしかしたら img 要素かもしれない。 そこで、id を見ている。 もしも、id が 'id-area-*' ( * には数値 ) なら…という具合だ。 ちなみに、正規表現を利用しており、id-area-([0-9]+) として数値部分を記憶するようにしている。 記憶した数値部分を取得するには、戻り値( ここでいう ret )を使って ret[1] とすれば取得できる。 これが番号代わりだ。 引き算をしているのは、もともと文字列だったのを数値に変換するため。 という感じ。 あとはまぁグローバル変数はやめたほうがいいとかいろいろ…。
- ai10
- ベストアンサー率27% (3/11)
<<2>> それぞれの画像に対応するリンクを貼る。 について… 考え方は<<1>>とまったく同じだ。 [2-1] 変更させる画像 ( id = 'id-img' ) に、A タグで囲む。 <a href='最初にリンクさせるURL'><img id='id-img' src='最初に表示される画像パス'></a> ( a タグの書式については省く。) こんな感じ。 それぞれの画像に対応するリンク…というのは、 実は簡単なことで、画像を変更する際に、同時に a 要素の href 属性の内容を変えるだけでいいんだ。 (リンク先を変えるってことね) [2-2] リンク先を変更するプログラムをSCRIPT側に追加する。 URLリストを配列として用意しておくと楽だ。 var arrUrls = [ 'http://www.google.co.jp/', 'http://www.goo.ne.jp', ... ]; URLだと1行で書きづらくなってくるので、次のようにして書いてもかまわない。 var arrUrls = [ 'http://www.google.co.jp/', 'http://www.goo.ne.jp/', 'http://jp.msn.com/' // ←最後のものにはカンマ(,)は必要ない ]; という具合だ。 ちなみに、上から順番に、A.jpg, B.jpg, ... に対応するURLだ。 URLを変更するプログラムについては、 画像変換と同じタイミングでURLを変更するわけだから、 Change 関数の中に書いてしまっても問題はない。というか、それしかない。 function Change ( index ) { // 画像変更 var obj = document.getElementById( 'id-img' ); obj.src = arrImgs[index].src; // リンク先変更 // 1 : a 要素を取得して、それを変数 obj に入れる。( obj 再利用 ) // このとき、obj にはもともと img 要素が入っており、 // img 要素の親を辿れば、a 要素が取得できる。 // 「親を辿る」方法として、obj.parentNode がある。 // それを obj に代入すればOKなわけだ。 obj = obj.parentNode; // 2 : リンク先を変更する。 // arrUrls[index] とすれば(変更予定の)URLが取得できる。 // それを obj.href に代入してやればいい。 obj.href = arrUrls[index]; } ここまでで、次のようなソースになっていると思う。 最初に表示されるリンク先は、http://www.google.co.jp/としといた。 ------------------------------------------------------------------------------------ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang='ja'> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta http-equiv="Content-Style-Type" content="text/css"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <script type='text/javascript'> var arrImgs = []; arrImgs[0] = new Image(); arrImgs[0].src = 'images/A.jpg'; arrImgs[1] = new Image(); arrImgs[1].src = 'images/B.jpg'; arrImgs[2] = new Image(); arrImgs[2].src = 'images/C.jpg'; var arrUrls = [ 'http://www.google.co.jp/', 'http://www.goo.ne.jp/', 'http://jp.msn.com/' // ←最後のものにはカンマ(,)は必要ない ]; function Change ( index ) // index には、画像リストの番号( 0 ~ )が入る { // 画像変換 var obj = document.getElementById( 'id-img' ); obj.src = arrImgs[index].src; // リンク先変更 obj = obj.parentNode; obj.href = arrUrls[index]; } </script> </head> <body> <a href='http://www.google.co.jp/'><img id='id-img' src='images/A.jpg'></a> <br> <img src="images/map.gif" usemap="#ClickableMap1" width="250" height="150"> <map id="ClickableMap1" name="ClickableMap1"> <area shape="rect" coords="20,25,116,64" onmouseover='Change(0)'> <area shape="circle" coords="67,101,25" onmouseover='Change(1)'> <area shape="polygon" coords="178,72,138,132,218,132" onmouseover='Change(2)'> </map> </body> </html> ------------------------------------------------------------------------------------ (全角スペースが使われています。)
- ai10
- ベストアンサー率27% (3/11)
リモートロールオーバーによる画像変換というのは、 1つの画像に対してですか?それともエリアごとにそれぞれ画像が割り当てられているのでしょうか? <1つの画像に対して> エリア1に対して画像1を画像Aに変え、 エリア1に対して画像1を画像Bに変え、 … なのか、 <エリアごとに画像が割り当てられている> エリア1に対して画像1-1を画像1-2変え、 エリア2に対して画像2-1を画像2-2変え、 … とりあえず、map の各 area 要素に対して mouseover のイベントをつけてやれば 大丈夫だとは思います。 少し考えてみて下さい。 また、map の name は廃止予定のはずなので name と id 両方書くことをオススメします。 以下のソースは、<1つの画像に対して>の場合を想定して作りました。 たとえば、 id='id-img' の画像を エリア1 (id='id-area-0') にマウスがきたら images/A.jpg に エリア2 (id='id-area-1') にマウスがきたら images/B.jpg に エリア3 (id='id-area-2') にマウスがきたら images/C.jpg に 入れ替えるものです。 ※イベントはdocumentのmouseoverを監視しています。 ------------------------------------------------------------------------- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang='ja'> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <script type="text/javascript"> ( function ( toImageObject, mouseOverEvent ) { var arrImgs = [ "images/A.jpg", "images/B.jpg", "images/C.jpg" ]; toImageObject( arrImgs ); // Imageオブジェクトに変換 mouseOverEvent = mouseOverEvent( arrImgs ); //@cc_on document./*@if (@_jscript) attachEvent( 'on'+ @else@*/ addEventListener( /*@end@*/ 'mouseover', mouseOverEvent, false ); // destroy arrImgs = toImageObject = mouseOverEvent = null; } )( function ( arr ) { var i, I, tmp; for( i=0, I=arr.length; i<I; i++ ) { (tmp = new Image()).src = arr[i]; arr[i] = tmp; } // destroy i = I = tmp = arr = null; }, function ( arrImgs ) { var _regexp = { id : /^id-area-([0-9]+)$/ }; return function ( evt ) { var ret, obj, idx; obj = evt.srcElement || evt.target; if( (ret = obj.id.match( _regexp.id )) ) { idx = ret[1] - 0; obj = document.getElementById( 'id-img' ); if( ! obj ) return; obj.src = arrImgs[idx].src; } // destroy evt = ret = obj = idx = null; } } ); </script> </head> <body> <img id='id-img' src='images/A.jpg' width="100" height="100"><br> <img src="images/map.gif" usemap="#ClickableMap1" width="250" height="150"> <map id="ClickableMap1" name="ClickableMap1"> <area shape="rect" coords="20,25,116,64" id="id-area-0"> <area shape="circle" coords="67,101,25" id="id-area-1"> <area shape="polygon" coords="178,72,138,132,218,132" id="id-area-2"> </map> </body> </html> ------------------------------------------------------------------------- 注: [1] 全角スペースが使われています。 [2] 特殊な書き方をしているのは、私自身の勉強のためでもあり、他意はありません。
お礼
補足の訂正です。 >希望していたのは、お教えいただいた、 エリアごとに画像が割り当てられている ものでした。 >希望していたのは、お教えいただいた、 <1つの画像に対して> でした。 すみません…。
補足
お返事遅くなって申し訳ありません。 ご丁寧に本当にありがとうございました! 希望していたのは、お教えいただいた、 エリアごとに画像が割り当てられている ものでした。 説明不足ですみません。 もしよろしければ、エリア1 にマウスがきて A.jpgやB.jpgが表示されたときのその画像にそれぞれの リンクを貼る方法を教えていただければ幸いです。 javascriptのことがほとんどわかっていないので、 基本的なことでしたら申し訳ないのですが、 よろしくお願いいたします。
お礼
とても詳しく説明してくださってありがとうございました。 正直、私の知識がとても残念なのでわからない部分もあるのですが、 シンプルなソースになり、本当に感謝しています。 画像が分かれている場合のものも説明してくださり、 今後使うときにも役に立ちますし、検索等でここを参考にされる方も きっと出てくると思います。 大変有意義なものをありがとうございました。 感動した!