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を探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
至急!GetElementById でtdの...
-
一覧から選択した行の行番号を...
-
tableの任意行にfocusをあてる
-
jQueryで行の移動
-
【JQuery】テーブルで行選択さ...
-
JavaScriptでテーブルの行入れ替え
-
JavaScriptで特定のtdタグにcla...
-
週だけのカレンダーを作成する方法
-
特定<table>内の<td>の色を変える
-
return trueとreturn falseの用...
-
<input>の選択肢をプルダウンメ...
-
<JavaScript>tableタグを入力不...
-
onclickで2個指定するには?
-
【javascript・PHP】プルダウン...
-
javascriptでセレクトボックス...
-
javascriptでASPにデータを渡す
-
javascriptで合計金額を算出し...
-
submitするとなぜか2度実行する
-
入力チェックの外部スクリプト...
-
hiddenのvalueの値を変えたい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ハイパーリンクを別ウインドウ...
-
特定<table>内の<td>の色を変える
-
JavaScriptで特定のtdタグにcla...
-
プルダウンで選択すると、DBの...
-
マウスをブラウザの外に出した...
-
至急!GetElementById でtdの...
-
一覧から選択した行の行番号を...
-
JavaScriptでテーブルの行入れ替え
-
【UWSC】HTML内のある部分を抽...
-
スクロールバーの表示位置を変...
-
tableの任意行にfocusをあてる
-
テーブルの変数について
-
チェックボックスにチェックが...
-
Excelで作ったhtmlファイルのサ...
-
Selenium.ChromeDriverの使い方...
-
特定の文字列を挿入
-
javascript クリックすると、あ...
-
テーブルで複数行をまとめて非...
-
javascriptでボタンを押すたび...
-
クリックされた罫表セルの行番...
おすすめ情報