はじめまして。
現在 prototype.js 1.4.0 を利用して、Web ページの作成を行っているのですが、イベントの登録 (Event.observe)でやりたいことと、異なる動作になってしまい困っているところです。
[ やりたいこと ]
javascript側で動的に生成した各要素 (div) に対して moueover & mouseout のイベントを割り当てる。mouseover 時には background の値を変え mouseout 時には background の値を元(transparent)に戻す。
[ 困っていること ]
各要素のmouseover & mouseout 時には各要素の背景色が変更されるはずなのに、一番最後に生成した要素の背景が変更されてしまう。
[ コード ]
<html>
<head>
<script type="text/javascript" src="prototype.js" ></script>
<script type="text/javascript">
view = new Class.create();
view.prototype = {
initialize:function() {
var view = $('viewContents');
var idName = 'test';
for (var i=0; i<10; i++) {
var id = idName + i;
var d = document.createElement('div');
d.id = id;
d.innerHTML = id;
view.appendChild(d);
Event.observe(d,'mouseover',function() {d.style.background='#aaa';}.bind(this),false);
Event.observe(d,'mouseout' ,function() {d.style.background='transparent';}.bind(this),false);
Event.observe(d,'click' ,function() {alert(d.id);}.bind(this),false);
}
}
}
</script>
</head>
<body>
<p><input type="button" onclick="new view();" value="取得"></p>
<div id="viewContents"></div>
</body>
</html>
となります。
なにか基本的なところが間違っているのでしょうか?
よろしくお願いいたします。
No.2ベストアンサー
- 回答日時:
#1>…ということでよろしいのでしょうか?
私の理解している処(なので、間違っているかも知れません、話半分で聴いて下さい)では、
コールバック関数にbind(this)すると言うことは、this(この場合は、view)の中でその関数を呼び出すことです。
ここで呼び出される関数は、定義された時の(dの)値を中味として実行されるのではなくて、呼び出された時にその(dの)中味を実行するので、ループが終了した最後のd(ループで置き換えられるから)が使われるのだと思います。(つまり変数名でアクセスされその定義した時の中味にアクセスされるのではない)
なので、この場合、dを1つの変数でアクセスするのでなく、それぞれのオブジェクトでアクセスできた方がいいとわかります。
それで、this.div にしてみました。
view のままでも配列にして保持するとか
Event.observe を使わないで
d.onclick=function(){alert(this.id)};
のようにもできると思います。
また、
click:function(){
alert(this.div.id);
}
のようにメソッド定義をして
Event.observe(this.div,'click', this.click.bind(this),false);
のようにもできると思います。(どちらかというと、こちらの方がbindしてるという感じになるような)
丁寧なご説明ありがとうございます。
>呼び出された時にその(dの)中味を実行するので、ループが終了した最後のd(ループで置き換えられるから)が使われるのだと思います。
で、何とかですが理解することができました。
ありがとうございました。
No.1
- 回答日時:
prototype.js って普段使っていないのでオオボケかましてたらすみません。
>基本的なところが間違っているのでしょうか?
質問にあるソースでbind(this) されている'this' は、何かということを勘違いされているのだと思います。
なるべく、元の形を活かして書き直してみました。
----------------------------------------------------------------
<script type="text/javascript">
cDiv = new Class.create();
cDiv.prototype = {
initialize:function(id, html){
this.div = document.createElement('div');
this.div.id = id;
this.div.innerHTML = html;
//better? : bind -> bindAsEventListener
Event.observe(this.div,'mouseover', function(){this.div.style.background='#aaa';}.bind(this),false);
Event.observe(this.div,'mouseout', function(){this.div.style.background='transparent';}.bind(this),false);
Event.observe(this.div,'click', function(){alert(this.div.id);}.bind(this),false);
}
};
view = new Class.create();
view.prototype = {
initialize:function() {
var view = $('viewContents');
var idName = 'test';
for (var i=0; i<10; i++) {
var id = idName + i;
var div = new cDiv(id, id).div;
view.appendChild(div);
}
}
};
</script>
書き直していただいたコードで実行することにより、期待した動作になりました。ありがとうございます。
>bind(this) されている'this' は、何かということを勘違いされているのだと思います。
ですが、動的に生成した要素の Class オブジェクト一つ一つにイベントを登録しないといけないのに、ひとつしか生成していない View オブジェクトにイベントを割り当てたために、おかしな動作になってしまった。
ということでよろしいのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- JavaScript コードレビューをお願いします。 1 2022/07/16 05:38
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/30 09:10
- JavaScript プログラムがうまく動きませんレビューお願いします 1 2022/07/10 05:08
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- JavaScript GoogleChart 階層ごとのブロックの長さを個別に設定したい 1 2022/07/06 14:27
- JavaScript javascriptのちょっとした動作不良(原因は突き止めたのですが) 1 2023/06/15 19:58
- JavaScript 入力フォームの javascript で メールアドレスの正規チェックをを行い、ボタンをクリックして 2 2022/04/27 16:06
- JavaScript javascript作成してます。ラジオボタンで判定するコードを書いてます。 1 2023/07/18 11:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
<a>タグのテキストを取得
-
ActiveXobjectが作成できない
-
innerHTML実行後のイベント
-
javascriptでスロットゲームを...
-
onchangeイベントを使ってspan...
-
画像上のクリックした場所が分...
-
Enterで次の入力項目へ進むには?
-
div要素内の全input要素をdisable
-
【Tabキー】特定の範囲内だけで...
-
javascript 特定のタグのidの存...
-
同じIDで定義した要素の配列を...
-
JavaScriptで文字列の特定文字...
-
jspからjavascriptの変数引継ぎ
-
C#テキストボックスの文字を配...
-
javascriptとphpの連携で疑問
-
Latexに関する質問です。
-
window.openでタイトル名の指定
-
Boolean型配列中のTrueの有無を...
-
翌月を取得するGASが分かりません
-
Javascriptグローバル変数の値...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
<a>タグのテキストを取得
-
ActiveXobjectが作成できない
-
onchangeイベントを使ってspan...
-
HTML:Tableタグに対し、JavaScr...
-
任意の座標をクリックさせるには
-
モーダルダイアログウィンドウ...
-
innerHTML実行後のイベント
-
Click回数を数え、規定された回...
-
javascript 特定のタグのidの存...
-
[初心者]javascriptのfor文でな...
-
【Tabキー】特定の範囲内だけで...
-
javascriptでスロットゲームを...
-
JavaScriptとcookieを利用して...
-
日本語入力の禁止
-
javascriptで、表示されている...
-
javascriptで編集可能不可能の...
-
画像の一部を表示
-
DIV内のDIV要素を移動する。
-
javascript の 命令文の記述で...
-
重複しないくじの作り方がわか...
おすすめ情報