• 締切済み

JavaScriptでドロップダウンメニュー

を自力で実装したいのですがうまくいきません。 気になっているのは ddObj.onmouseoverと ddObj.onmouseout の上記2つのイベントハンドラ内の 変数iが親スコープでi==0であるはずなのに イベントハンドラ内だとなぜか i == 1となっているのです。 JavaScriptの練習のために書いています。 Jqueryなどは使いなくないのです。 どなたかJSにお詳しい方ご教授ください。 <title>JavaScript テスト</title> <script type="text/javascript"> <!-- try{ //ファイルがすべて読み込まれたら実行される処理 var onloadMethod = function onloadMethod(){ //初期状態ではドロップダウンメニューは表示されていない。 var defaultMenu = document.getElementsByTagName("dl"); for (var i = 0; i < defaultMenu .length; i++){ defaultMenu[i].style.position ="relative"; } var drop = document.getElementsByTagName("dt"); var ddObj = document.getElementsByTagName("dd"); for( var i = 0; i < drop.length; i++){ alert(i); //まずカテゴリー・メニューの簡易的なデザインを決める。 drop[i].style. width = "200px"; drop[i].style. height = "50px"; drop[i].style.backgroundColor = "#FF99FF"; //次に書くカテゴリー・メニューのマウスオーバーイベントハンドラを指定する。 alert(i); drop[i].onmouseover = function(){ alert(i); //まずはここではメニューリストを表示させるだけの処理を書く //各メニューリストはddタグ要素の中のliタグなのでまずdd要素の表示 ddObj.item(i).style.position = "absolute"; ddObj.item(i).style.top = "50px"; ddObj.item(i).style.visibility = ""; ddObj.item(i).style.backgroundColor="red"; }; drop[i].onmouseout = function(){ //alert(i); //カーソルのマウスオーバーが外れたらddタグ要素を非表示にする。 ddObj.item(i).style.visibility = "hidden"; ddObj.item(i).style.backgroundColor="blue"; //alert("00"); }; alert(i); } /* var list = document.getElementsByTagName("li"); for(var i = 0; i < list.length ; i++){ document.getElementsByTagName("li").item(i).onmouseover = function(){ drop.onmouseover(); }; document.getElementsByTagName("li").item(i).onmouseout = function(){ drop.onmouseout(); }; } */ }; //すべての要素の読み込み完了後の実行 window.addEventListener("load" ,onloadMethod,false); }catch(e){ document.write(e); } --> </script> </head> <body> <p>対象のドロップダウンメニュー(※dl要素が一つのカテゴリー・メニュー)</p> <dl class="dropdown" title="two"> <dt id="ddheader-two">メニューのカテゴリー名</dt> <dd id="ddcontent-two"> <ul> <li style="width:240px;height:30px;background-color:gray;"><a href="http://yahoo.co.jp">カテゴリ内メニュー01</a></li> <li style="width:240px;height:30px;background-color:gray;"><a href="http://yahoo.co.jp">カテゴリ内メニュー02</a></li> <li style="width:240px;height:30px;background-color:gray;"><a href="http://yahoo.co.jp">カテゴリ内メニュー03</a></li> <li style="width:240px;height:30px;background-color:gray;"><a href="http://yahoo.co.jp">カテゴリ内メニュー04</a></li> <li style="width:240px;height:30px;background-color:gray;"><a href="http://yahoo.co.jp">カテゴリ内メニュー05</a></li> </ul> </dd> </dl> <p>文字列</p> </body> </html>

みんなの回答

  • teketon
  • ベストアンサー率65% (141/215)
回答No.1

私も余りJavaScriptをやり込んでいるわけではありませんが、 おそらく、変数のスコープを勘違いされています。 JavaScriptの変数のスコープはブロックスコープ({})ではなく、関数スコープです。 変数iはforの初期化部で定義していますが、内部的にはonloadMethod宣言直後の定義と同じです。 ですから、forを抜ける際にi++してi=1になり、i<drop.lengthが偽となりforを終了しますが、 iの値は保持したままです。 そのため、alertで1が出ています。

1000vicki
質問者

補足

自己解決しました。 drop[i].onmouseover = (function (k){ return function (){ //alert(k); //まずはここではメニューリストを表示させるだけの処理を書く //各メニューリストはddタグ要素の中のliタグなのでまずdd要素の表示 ddObj.item(k).style.position = "absolute"; ddObj.item(k).style.top = "50px"; ddObj.item(k).style.visibility = ""; ddObj.item(k).style.backgroundColor="red"; } }(i)); どうやらクロージャーにしてやれば動くようです。

関連するQ&A