こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

すみませ~~ん!助けてぇ!

初心者です・・すいません!
どうしても解決できずに頭抱えています!!うぅ・・。

a要素をマウスオーバーしたらdiv要素のクラスが入れ替わるようにしたいと思い
こんなスクリプトを組んでみたんですが・・・できません。。
原因はたぶん function(){~~}の中身の記述の仕方が違うのかもと・・
そう思っています。

原因を教えていただけませんでしょうか??
ぜひご教授のほどよろしくお願いいたします。。お願いします!
HTML-------------------------------------------------------------------------
<body>
<a href="http://www.yahoo.co.jp/" class="waiwai"></a>
<a href="http://www.yahoo.co.jp/" class="waiwai" style="top:100px;"></a>
<a href="http://www.yahoo.co.jp/" class="waiwai" style="top:200px;"></a>
<a href="http://www.yahoo.co.jp/" class="waiwai" style="top:300px;"></a>
<div class="hare"></div>
<div class="hare"></div>
<div class="hare"></div>
<div class="hare"></div>
</body>


CSS-------------------------------------------------------------------------
.hare{ display:block; background:url(toumei.gif) no-repeat; width:300px; height:100px;}
.ame{ display:block; background:url(toumei2.gif) no-repeat; width:300px; height:100px;}
.waiwai{background:url(toumei.gif) no-repeat; width:300px; height:100px; position:absolute; display:block;}

javascript-------------------------------------------------------------------
window.onload = function(){

var hai = document.getElementsByTagName("div");
var waku = document.getElementsByTagName("a");

for (var i=0; i<waku.length; i++){
waku[i].onmouseover = function(){
hai[i].className="ame";
}
waku[i].onmouseout = function(){
hai[i].className="hare";
}
}
}

投稿日時 - 2009-02-24 15:28:59

QNo.4745251

困ってます

質問者が選んだベストアンサー

クロージャ(C系言語のスタティック変数に近い)を使う前に、
JavaScriptの基本とも言えるidを使った方法を自分で作れるようになった方がいいと思います。
クロージャはメモリリークというバグが作られる可能性がかなり高いです。
(IE7などの・・・と一部のブラウザだけを指定するような書き方をしている解説サイトもありますが、私が確認した限り、Firefox2、3、Safari3、IE6、7、Opera9、Netscape9、iCab3に影響します)


No.4の参照サイトで解説されていたので無名関数で書きましたが、
やはりある程度なれてないと理解しにくいと思います。。。

同じコードを一般的な関数の書き方で書き直してみました。
私が自分用や仕事で作るときは、モジュール化と可読性(とメモリリーク対策)を優先するため、こういう書き方をする方が多いです。


window.onload = function(){
var hai = document.getElementsByTagName("div");
var waku = document.getElementsByTagName("a");
for (var i=0; i<waku.length; i++){
waku[i].onmouseover = MouseOver(hai[i]);
waku[i].onmouseout = MouseOut(hai[i]);
}
};

function MouseOver(elm){ //このelmがクロージャ
return function(){elm.className="ame";};
}
function MoseOut(elm){ //このelmがクロージャ
return function(){elm.className="hare";};
}


> たとえば、「elm」なんですが、この引数の中身には何がはいってくるのでしょうか?
これなら見ればわかると思いますが、
見てわからないようなら、DOMよりも前の段階、「関数の作り方と使い方」から勉強し直す方がいいでしょう。


もっとアレンジするなら、関数に汎用性を持たせて1つにしたり、
No.7にもありますが、<a>の何番目と<div>の何番目が対応、ではなく、
「waiwaiクラスの何番目とhareクラスの何番目が対応」などもできると思います。

投稿日時 - 2009-02-27 03:14:42

お礼

なるほどーーー。
僕もクロージャを自分で調べてみました。でも・・よくわかりませんでしたww。
まだまだ勉強不足ですよね。。基本的には所にかえって再度チャレンジしてみたいと思います。

長々と本当にありがとうございました!

投稿日時 - 2009-02-27 11:04:24

ANo.9

このQ&Aは役に立ちましたか?

4人が「このQ&Aが役に立った」と投票しています

回答(9)

ANo.8

HTML-------------------------------------------------------------------------
<body>
<p><a href="http://www.yahoo.co.jp/" class="waiwai"><span></span></a></p>
...
</body>

CSS-------------------------------------------------------------------------
.waiwai span{ display:block; background:url(toumei.gif) no-repeat; width:300px; height:100px; }
.waiwai:hover span{background-image:url(toumei2.gif)}

投稿日時 - 2009-02-27 01:49:02

ANo.7

動きましたか~!よかったですね~^^;

クロージャーの説明は他の方にお願いするとして
多くのwepページで、<div>と<a>が対をなして
存在するのはごく限られた条件のみ。
実運用には、何か細工したほうが良いのかも?
すべての<div>とか<a>とか拾っているので参考までに。

投稿日時 - 2009-02-26 21:50:03

お礼

ご回答いただきましてありがとうございます!(ご連絡が遅くなりましあ・・)
まだまだ未熟者でして、勉強不足も甚だしいですよね・・w
参考になりましたありがとうございます!

投稿日時 - 2009-02-27 11:00:53

ANo.6

idを付けて、mouseoutを省くってのは?
<body>
<a id="a_0" href="http://www.yahoo.co.jp/" class="waiwai">aa</a>
<a id="a_1" href="http://www.yahoo.co.jp/" class="waiwai" style="top:100px;">bb</a>
<a id="a_2" href="http://www.yahoo.co.jp/" class="waiwai" style="top:200px;">cc</a>
<a id="a_3" href="http://www.yahoo.co.jp/" class="waiwai" style="top:300px;">dd</a>
<div id="b_0" class="hare">AA</div>
<div id="b_1" class="hare">BB</div>
<div id="b_2" class="hare">CC</div>
<div id="b_3" class="hare">DD</div>
</body>
<script type="text/javascript">
//@cc_on
(function(){
var m;
document./*@if(1)attachEvent('on'+ @else@*/addEventListener(/*@end@*/'mouseover', function (evt) {
var s, n, element = evt./*@if(1) srcElement @else@*/ target /*@end@*/;
if (m) m.className = 'hare';
if (n = element.id.match(/^a_(\d+)$/)) {
s = document.getElementById('b_'+n[1]);
if (m = s) s.className = 'ame';
}
}, false);
})();

</script>

投稿日時 - 2009-02-26 09:39:41

ANo.5

window.onload = function(){
var hai = document.getElementsByTagName("div");
var waku = document.getElementsByTagName("a");
for (var i=0; i<waku.length; i++){
waku[i].onmouseover = (function(elm){
return function(){elm.className="ame";};
})(hai[i]);
waku[i].onmouseout = (function(elm){
return function(){elm.className="hare";};
})(hai[i]);
}
};

理論はNo.1~4、その他過去ログに出ているとおりです。
クロージャはある意味基本だけど、ちょっと難しいと思います。

代わりに、たとえばIDを指定しておくというのはいかがでしょうか。
<body>
<a id="a_1" href="http://www.yahoo.co.jp/" class="waiwai">aaaaaa</a>
<a id="a_2" href="http://www.yahoo.co.jp/" class="waiwai" style="top:100px;">bbbbbbb</a>
<a id="a_3" href="http://www.yahoo.co.jp/" class="waiwai" style="top:200px;">ccccccc</a>
<a id="a_4" href="http://www.yahoo.co.jp/" class="waiwai" style="top:300px;">ddddddd</a>
<div id="div_1" class="hare">aaaaaaa</div>
<div id="div_2" class="hare">bbbbbbb</div>
<div id="div_3" class="hare">ccccccc</div>
<div id="div_4" class="hare">ddddddd</div>
</body>


<script>
window.onload = function(){
var waku = document.getElementsByTagName("a");

for (var i=0; i<waku.length; i++){
waku[i].onmouseover = function(){
var n= (この部分を考えてみてください。ヒント: this.id)
var div=(この部分を考えてみてください。ヒント: document.getElementById()とn )
div.className="ame";
};
waku[i].onmouseout = function(){
var n= (この部分を考えてみてください。)
var div=(この部分を考えてみてください。)
div.className="hare";
};
}
};
</script>

投稿日時 - 2009-02-25 09:23:02

補足

ご連絡遅れました・・。すいません。

教えて頂いた以下のスクリプト

window.onload = function(){
var hai = document.getElementsByTagName("div");
var waku = document.getElementsByTagName("a");
for (var i=0; i<waku.length; i++){
waku[i].onmouseover = (function(elm){
return function(){elm.className="ame";};
})(hai[i]);
waku[i].onmouseout = (function(elm){
return function(){elm.className="hare";};
})(hai[i]);
}
};


を使わせてもらいました!
うごきました!ありがとうざいます!

ただ、動いたのは良いんですが、分からない点が何点かありまして・・すみません。

ぜひ教えて頂きたいのですがよろしいでしょうか?

このスクリプトで所々でてくる、”waku[i].onmouseover=”という所以降スクリプトがどんな仕組みで結果を出しているのかがわからないんです。。すみません。

以下の部分をご説明いただける本当に助かります。
waku[i].onmouseover = (function(elm){
return function(){elm.className="ame";};
})(hai[i]);

ご教授いただけますでしょうか?

よろしくお願いいたします。



たとえば、「elm」なんですが、この引数の中身には何がはいってくるのでしょうか?

投稿日時 - 2009-02-26 19:26:19

ANo.4

No1です。

ご質問のコードはそれぞれのイベント処理に
 hai[0].className="ame"
 hai[1].className="ame"
     …
みたいに定義されることを期待して書いてたのではないのでしょうか?(あるいは [Object0].className みたいに…)
それが、hai[i].className="ame"になっているということに、まず気づいてほしいところ。
…で、それがうまくいかない原因ではないのかな?

また、haiを用いてアクセスするのなら、変数をグローバルで定義しておいたほうが良いのでは?
(試してみたら、undefinedにはならないみたいだけど)

方法としては、<a>と<div>を関連付けておいて、thisで渡して<div>を特定するか、あるいは、どうしてもインデックスiで定義したいというのなら、解決法のヒントは過去ログのこの辺に…
 http://oshiete1.goo.ne.jp/qa4406107.html

投稿日時 - 2009-02-24 17:48:50

ANo.3

> でも以下の形で作ったら反応しました。
> たとえばこんな感じ↓
> (これdiv要素に直接ロールオーバさせてクラスを入れ替えています。)
> window.onload = function(){
> var hai = document.getElementsByTagName("div");
> for (var i=0; i<hai.length; i++){
> hai[i].onmouseover = function(){
> this.className="ame"; ←直接なのでthisで参照しています。
> }
> hai[i].onmouseout = function(){
> this.className="hare";
> }
> }
> このやりかただと、「onmouseover時に変数iは4」&「onmouseoverするときにはfor文終わってしまっているでしょ」の二つがクリアできてしまっているんです。クラスがしっかりと入れ替わります。

当然よ。
onmouseover、outで呼び出されるfunction内でiは使っていないでしょ?
だから成功するの。

onmouseover、outのイベント付加は成功しているわ。
失敗しているのはそのイベント内の処理なのよ。
最初の例だとonmouseover・・・もうoutは面倒だから書かないわね、
onmouseoverのイベント内で変数iを使っているでしょ?
これが大間違い。

投稿日時 - 2009-02-24 17:31:09

お礼

ご連絡が遅くなりまして申し訳ありません・・なんとか解決できました!
もっと勉強しないとだめですね。。こんなにもたくさんの方からご回答いただきました本当に自分のダメさ加減に驚きです。。w

またわからないことがあったときにご無礼するとはおもいますが、その時はどうぞよろしくお願いいたします。

投稿日時 - 2009-02-27 11:06:55

ANo.2

上手くいかない
というのが
具体的にどうなっちゃっているわけ?
そこを書いて欲しいわ。
こっちが一手間増えるじゃない。

上手くいかない理由は簡単よ。
onmouseover時に変数iは4になってしまっているの。
だって、onmouseoverするときにはfor文終わってしまっているでしょ?

投稿日時 - 2009-02-24 16:52:05

補足

ご回答いただきましてありがとうございます。
具体的にというとなんですが、マウスオーバーしても何も反応がしないんです。。
もし成功しているなら、div要素の画像が変更される予定です。


>onmouseover時に変数iは4になってしまっているの。
>だって、onmouseoverするときにはfor文終わってしまっているでしょ?

確かに、変数iは4でした。alert()で調べたらなってました。
でも以下の形で作ったら反応しました。
たとえばこんな感じ↓
(これdiv要素に直接ロールオーバさせてクラスを入れ替えています。)
window.onload = function(){
var hai = document.getElementsByTagName("div");
for (var i=0; i<hai.length; i++){
hai[i].onmouseover = function(){
this.className="ame"; ←直接なのでthisで参照しています。
}
hai[i].onmouseout = function(){
this.className="hare";
}
}
このやりかただと、「onmouseover時に変数iは4」&「onmouseoverするときにはfor文終わってしまっているでしょ」の二つがクリアできてしまっているんです。クラスがしっかりと入れ替わります。

どうしてでしょうか?

投稿日時 - 2009-02-24 17:11:03

ANo.1

多分、無名ファンクションの内容が、イベント定義時に評価されずに、実際の実行時(イベント発生時)に評価されているので、質問者様の思惑と違った結果になっていると思われます。

イベント時のファンクション定義の最初に、alert(i);とかalert(hai[i].className);などを入れて実験してみればわかると思います。

投稿日時 - 2009-02-24 16:11:48

補足

ご回答ありがとうございます。
ご指摘頂いたとおりに実験してみました。

ここの部分です↓
for (var i=0; i<waku.length; i++){
waku[i].onmouseover = function(){
alert(hai[i].className);
hai[i].className="ame";
alert(hai[i].className);
}
とこんな感じでに二つ配置しました。

すると、最初のアラートで「hare」と表示され後のアラートでame表示されました。
ということはameになっていることは確かですよね?
でもieブラウザでみているんですが、なにも変化がないんですよね。

どうしてでしょうか?「i」にはいってる数はマウスオーバーしているa要素をしっかりと取得できるいるのでしょうか??

すみません。。どうかお願いいたします!

投稿日時 - 2009-02-24 16:29:47

あなたにオススメの質問