
jQueryを学習中の者です。
現在、パララックス効果のサンプルコードを参考にしているのですが、理解できずに困っています。
その内容は各ブロック要素をeachでループさせ、ループの中でウインドウのスクロールイベントを登録しコールバック関数で細かい設定をしていくというものです。
理解できないというのは、以前 javasctiptでのfor文による要素へのイベント登録で「イベントでも渡す関数は参照のみです。新たに関数を自動で作成してくれるような事は決してありません。」と説明が有り、コールバック関数内に変数を使うとイベント発生時に変数を参照した時、ループの最後で格納した値になるので、この事は理解し注意もするようにしていました。
しかし、今回のサンプルコードではforとeachの違いはあるけれど、コールバック関数に変数を使っているのに、その変数が別々の値を持っています。
最初はjQueryとjavascriptの挙動の違いかなと思い、以前のfor文のコードを下の様にjQueryで書き替えても結果は一緒でした。
取り留めの無い文章になってしまいましたが、どうして下の2つコードが違う結果になるのかを解り易く説明していただけませんでしょうか。
<table border="1">
<tr><td></td><td></td>...</tr>
...
</table>
<script>
(1)//これだと、駄目…どのtdのイベントでも最後のtdが反応
$(function(){
for(var i =0 ,len=$('td').length;i < len; i++){
var td=$('td').eq(i);
td.mouseover(function(){ td.css('background-color','red');});
td.mouseout(function(){ td.css('background-color','');});
}
});
(2)//これだとOK…ちゃんと各tdが反応する。
$(function(){
$('td').each(function(index,elem){
var td=$(elem);
td.mouseover(function(){ td.css('background-color','red');});
td.mouseout(function(){ td.css('background-color','');});
});
});
</script>
*今回の質問はどう対処したら良いのかという類ではありません。
両方とも変数 td にjqueryオブジェクトを格納して、同じ形式でイベント登録しているのに違う結果になるという事が壁に成ってます。
ネットでいくら調べても構文の説明やサンプルコードは溢れていますが、この様な事例に触れた物が皆無です。
forとeachの違いなんて基本的なことで恥ずかしいのですが、お願いします。
No.2ベストアンサー
- 回答日時:
01function A(){
02 var x = 0;
03
04 function B(){
05 var x = 2;
06 console.log(x);
07 }
08
09 function C(){
10 console.log(x);
11 }
12
13 x = 1;
14 B();
15 C();
16 x = 3;
17 B();
18 C();
19}
B/C関数を定義・・・4行目.9行目
B/C関数を実行・・・14行目.15行目.17行目.18行目
さて、各関数のxは何が表示されるでしょうか?
B関数は、A関数のxとはB関数のxを使用します。
対してC関数はxの宣言が無いので、A関数のxを使用します。
その為
14行目のB関数は2を表示
15行目のC関数は1を表示(13行目で1を入れている)
17行目のB関数は2を表示
18行目のC関数は3を表示(16行目で3を入れている)
これを理解したら、質問の内容に戻って(2)を少し分解してみましょう。
$(function){
function A(index, element){
var td=$(elem);
function B1(){ td.css('background-color','red'); }
function B2(){ td.css('background-color','');}
td.mouseover(B1);
td.mouseout(B2);
}
$('td').each(A);
};
B1/B2関数のtdはA関数のtdが使われるのは理解できると思います。
A関数は$.each関数で何度も実行されますが、
B1/B2関数で使われるtdは各A関数が実行した時のtdなので、正しく動くわけです。
eachではなく、以下のようにA関数を実行したと考えると分かりやすいかもしれません。
var $td = $('td');
A(0, $td[0]);
A(1, $td[1]);
再度の回答と詳細な説明、ありがとうございます。
回答の読み初めで、変数のスコープは分かってるんだけどな…と生意気な事を思ってしまいましたが、その後の分解式で目から鱗が落ちました。
そうですよね、forは要素の数だけ処理を繰り返してるだけ、eachは関数の実行を繰り返してる。
今まではeachを使っても取得や設定だけで、jQueryで初めてeachによる関数の実行に触れたので、思い込みで視界が狭くなっていたと反省してます。
これで、先に進めます。
ありがとうございました。
No.1
- 回答日時:
変数は関数の先頭で宣言されたものとして扱われます。
よって、(1)は以下と同等です。
$(function(){
var td;
for(var i =0 ,len=$('td').length;i < len; i++){
td=$('td').eq(i);
td.mouseover(function(){ td.css('background-color','red');});
td.mouseout(function(){ td.css('background-color','');});
}
});
問題の関数が実行される時、forループは回り後っているので、tdの中身は最後のtd
そのため(1)はうまく動きません。
詳しく知りたい場合は、javascriptの変数スコープについて調べると良いです。
回答、ありがとうございます。
おしゃる通りで(1)のコードの結果は正しいというか、自分の理解に沿ったものになります。
しかし、理解できないのは(2)のコードの結果です。
イベント登録している変数tdとコールバックの関数式のtdとの結び付きはループ処理内では出来ていないと、認識しているのですが、何故か(2)では各セルでコールバック関数が反映しちゃてるんですよね。
ループ処理でもforとeachは結果が違う物なのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript EasyUIのSubGrid(jquery)におけるObjectに入れた連想配列について 1 2022/05/02 11:21
- JavaScript jQueryで同じクラス名のものを別物として扱いたい 1 2022/06/17 14:14
- AJAX JavascriptからPHPへのAjax通信でnullが返ってくる 3 2022/08/03 22:00
- HTML・CSS テーブルタグのセルの幅の一部だけを指定 1 2023/03/12 12:02
- HTML・CSS 【CSS】:hasで可能? imgを含むtr要素を選択したい 1 2022/11/17 14:36
- Visual Basic(VBA) Selenium.ChromeDriverの使い方について 7 2022/09/22 06:43
- PHP htmlで複数の個数入力欄を表示させるには 1 2022/09/20 03:11
- MySQL SQL任意に並び替えをしたい 2 2023/08/28 10:47
- HTML・CSS 自身のHPにYouTube動画を貼り付けるのが出来なくなり困ってます 1 2022/11/11 10:44
- 工学 【制御工学】単位ステップ応答の遅れ時間の求め方(令和2年度の機械設計技術者試験(制御工学)の問題) 3 2022/11/02 10:51
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・「これはヤバかったな」という遅刻エピソード
- ・初めて自分の家と他人の家が違う、と意識した時
- ・いちばん失敗した人決定戦
- ・思い出すきっかけは 音楽?におい?景色?
- ・あなたなりのストレス発散方法を教えてください!
- ・もし10億円当たったら何に使いますか?
- ・何回やってもうまくいかないことは?
- ・今年はじめたいことは?
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
一覧から選択した行の行番号を...
-
jQueryのプラグイン「Tablesort...
-
ハイパーリンクを別ウインドウ...
-
COBOLで作ったテキストファイル...
-
Tablesorteを2行一組でソートする
-
HTML中のTABLEのデータを抽出す...
-
JavaScriptでテーブルの行入れ替え
-
tableの任意行にfocusをあてる
-
テーブル内に表示されている数...
-
特定<table>内の<td>の色を変える
-
「オブジェクトは、このプロパ...
-
テーブル内に表示されている数...
-
テーブルで複数行をまとめて非...
-
チェックボックスにチェックが...
-
JSで、テーブルのある行のみ、...
-
クリックされた罫表セルの行番...
-
jspでのArrayListの値の表示
-
テーブル行のクリックでチェッ...
-
JavaScriptでテーブルをクリッ...
-
javascript クリックすると、あ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
JavaScriptで特定のtdタグにcla...
-
一覧から選択した行の行番号を...
-
ハイパーリンクを別ウインドウ...
-
tableの任意行にfocusをあてる
-
特定<table>内の<td>の色を変える
-
プルダウンで選択すると、DBの...
-
チェックボックスにチェックが...
-
【UWSC】HTML内のある部分を抽...
-
至急!GetElementById でtdの...
-
マウスをブラウザの外に出した...
-
HTML中のTABLEのデータを抽出す...
-
クリックされた罫表セルの行番...
-
Selenium.ChromeDriverの使い方...
-
スクロールバーの表示位置を変...
-
jQueryでクリックされたテーブ...
-
Excelで作ったhtmlファイルのサ...
-
jQueryで行の移動
-
リンク色の変更
-
jquery datatablesを使用 イン...
-
JavaScriptでテーブルをクリッ...
おすすめ情報