• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:【jQuery】for文ではイベント登録できない?)

【jQuery】for文ではイベント登録できない?

mtaka2の回答

  • ベストアンサー
  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.1

JavaScriptの言語仕様の問題です。 forループが終わってイベント登録が完了した時点では、変数iは3になっています。 その後、ユーザー操作でマウスのクリック動作した時に、イベント関数が呼び出されますから、 > $(divArray[i]).animate({width: "0px"}, "slow", "swing"); この部分は、全て > $(divArray[3]).animate({width: "0px"}, "slow", "swing"); として処理されることになります。 そのため、期待通りの動作にならないのです。 対策ですが、 --- jQuery(function($){  var buttonArray = ["#button0", "#button1", "#button2"];  var divArray = ["#box0", "#box1", "#box2"];  function setCallback(i) {   $(buttonArray[i]).click(function(){    $(divArray[i])).animate({width: "0px"}, "slow", "swing");   });  }  for(i=0; i<buttonArray.length; i++){   setCallback(i);  } }); --- のように、イベント設定処理を関数化すれば、ループ中で関数呼び出しにより毎回新たな変数iが作られますから、期待通りの結果になるかと思います。 さらに、無名関数を使えば、 --- jQuery(function($){  var buttonArray = ["#button0", "#button1", "#button2"];  var divArray = ["#box0", "#box1", "#box2"];  for(i=0; i<buttonArray.length; i++){   (function(i) {    $(buttonArray[i]).click(function(){     $(divArray[i])).animate({width: "0px"}, "slow", "swing");    })(i);  } }); --- のように書くこともでき、もうちょっと簡潔になります。

icle
質問者

お礼

mtaka2様、ご回答ありがとうございます。  >>JavaScriptの言語仕様の問題です。  >>forループが終わってイベント登録が完了した時点では、変数iは3になっています。  >>その後、ユーザー操作でマウスのクリック動作した時に、イベント関数が呼び出されますから なるほど…! forループ毎にイベント登録され、それを呼び出してくれるのではなく、 clickイベント時にループ完了時点の変数iで呼び出されるのですね。 非常によく理解することができました。 また、対策の具体例を2つも提示して頂き、大変助かります。 どちらも試したところ、期待する動作を得ることができました。 jQueryの無名関数は、あらゆる場面で万能ですね…。 引き続き勉強していきたいと思います。 本当にありがとうございました!

関連するQ&A

  • jquery:animate中にイベントを付与

    #box{width:100%;height:100%;position:relative;} #idou{width:3000px;height:100%;position:absolute;} #ugoku{position:absolute;top:-300px;right:-1500px;} a{display:block;width:100px;height:100px;right:0;top:100px;} <div id="box"><div id="idou"><img id="ugoku" src="*.gif" width="300" height="300"><a href="">左に移動</a></div></div> ・jQuery(1.7.1) ・mousewheel.jsを使用、var scrollInt=100;$('html').mousewheel(function(event,mov){$("html,body").css("left","-="+(scrollInt*mov)+"px");});で通常は横移動するソース。 ・$("a").click(function(){$("#idou").animate({left:0},"slow");});でリンクをクリックすると左に戻す。この時の#ugokuが問題。 ・移動の角度は50度で設定、#idouのleftが-1000~-1500pxの間というような特定の間に#ugokuの画像を画面の右上から左下にanimateで流したい。 最後の項目をやろうとして完全に行き詰ってしまって困っています。 どちらかというと数学の問題かもしれません。 animate動作中に、#idouのleftが~pxになったときを拾うようなイベントは存在するのでしょうか?その他良いやり方やURLあれば教えて頂けると幸いです。 よろしくご教授ください。

  • (jQuery)どこがエラーなのか分からない

    ●質問の主旨 下記のコードはどこが間違いでしょうか? Javascriptコンソールでも特にエラー表示がされません。 ご存知のかたご教示願います ●コードの意図 1.ボタン要素(button)をクリック 2.非表示(none)にされていたdiv要素(赤い正方形)が出現する ●コード (click.html) <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>JavaScriptの勉強</title> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> </head> <body> <h1>JavaScriptの勉強</h1> <script> $(function() { $("button").click(function() { $("target").show('slow'); }); }); </script> <p><button id='button'>クリック</button></p> <div id="target" style="display"; none; width: 150px; height:150px; background-color: red;></div> </body> </html>

  • jQueryのforループ時のanimate

    jQueryにて下記のように 配列にて登録した要素に対して forループにてanimateを実行し、 completeで、animate完了後の動作を実行したいのですが、 forループにて複数に対して処理を行った際の挙動がおかしく、 動作を実行する前にcompleteの処理が走ってしまいます。 どのようにすれば、forループで複数のanimate処理をおこなっても 動くことができるようになるのか、 教えて頂けますよう宜しくお願いいたします。 -------------------------------------------------------------------- $(document).ready(function () {  for(i=0; i<10; i++){   pArray($('p').eq(i));  };  for(i=0; i<10; i++){   pArray[i].stop().animate({left: -100 * i}, {duration:1500, easing:'swing',complete:aaa()});  }  function aaa(){   alert('完了')  } }

  • jQueryを使ってランダムに表示

    jQueryを使って5つのボックス要素を、ランダムに3つ表示させています。 現在はページを読み込むたびに表示を切り替えていますが、これを「一定時間で表示を切り替え」に変更する事は可能でしょうか? できればjsのみの修正でできれば良いのですが…。 どなたかお助けください。よろしくお願いいたします。 jsとhtmlは以下のようにしています。 jQuery(function($) { $.fn.extend({ randomdisplay : function(num) { return this.each(function() { var chn = $(this).children().hide().length; for(var i = 0; i < num && i < chn; i++) { var r = parseInt(Math.random() * (chn - i)) + i; $(this).children().eq(r).show().prependTo($(this)); } }); } }); $(function(){ $("[randomdisplay]").each(function() { $(this).randomdisplay($(this).attr("randomdisplay")); }); }); }); <div randomdisplay="3"> <div id="box">ランダム1</div> <div id="box">ランダム2</div> <div id="box">ランダム3</div> <div id="box">ランダム4</div> <div id="box">ランダム5</div> </div>

  • jQuery イベントの繰り返し

    jQuery イベントの繰り返し ボタンが.button1から.button10まであり、それぞれを押すと .imgareaに1.ipgから10.jpgまでを表示させたいと思っています。 jQueryで下記のように書いたのですが、 最後のiが10のときのイベントしか反映されません…。 うまく記述するにはどうすればよいでしょうか? よろしくお願いいたします。 for(i=1; i<=10; i++){ $(".button"+i.toString()).click(function(){ $(".imgarea").attr("src",i.toString()+".jpg"); }) }

  • JQUERYについて教えてください。

    JQUERYについて教えてください。 readyがDOMを読み終わってから実行しろという意味は分かったのですが、 あったりなかったりするfunction()はどんな意味なのでしょうか? function(){ $(this).stop().animate({'marginBottom':'60px'},150); },function(){ $(this).stop().animate({'marginBottom':'0px'},120); こちらにあるのですがメソッドに一個必須なのでしょうか? 例 <script type="text/javascript"> $(document).ready(function(){ $('div#goto_top').hover( function(){ $(this).stop().animate({'marginBottom':'60px'},150); },function(){ $(this).stop().animate({'marginBottom':'0px'},120); </script>

  • jQuery 円周上に配置した要素を加工したい

    jQuery 円周上に配置した要素を加工したい ここに円周上に等間隔に要素を配置するコードがあります。 これを下記の要件を満たすためには、どんなコードにしたらよいですか? <要件> ・基準点を赤丸で表示させる ・時計の文字盤のような数字の配置にする(真上がゼロ) ・円内の文字が上下左右とも、中央に来るようにする ・数字は赤丸を天にした向きに表示させる <script src='https://code.jquery.com/jquery-3.7.0.min.js'></script> <style> .main-board { position: relative; width: 300px; } .circle-box { } div.item { position: absolute; width: 40px; height: 40px; -webkit-border-radius: 20px; -moz-border-radius: 20px; border-radius: 20px; background-color: #0dd; } </style> <section class="main-board"> <section class="circle-box"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </section> </section> <script> $(function(){ var item_num = $('div.item').length; var deg = 360.0 / item_num; var red = (deg * Math.PI / 180.0); var circle_r = $("div.item").width() * 2.5; $('div.item').each(function(i, elem) { var x = Math.cos(red * i) * circle_r + circle_r; var y = Math.sin(red * i) * circle_r + circle_r; $(elem).css('left', x); $(elem).css('top', y); $(elem).text(i); }); }); </script>

  • どうしてもわかりません カルーセル

    $(function(){ $("#s2").click(function(){ $("#s4").animate({marginLeft:parseInt($("#s4").css("marginLeft"))-300+"px"},"slow","swing", function(){ $("ul.s5:first").appendTo("#s4"); $("#s4").css("marginLeft","0px"); }); }); $("#s6").click(function(){ $("#s4").animate({marginLeft:parseInt($("#s4").css("marginLeft"))+200+"px"},"slow","swing", function(){ $("ul.s5:lest").appendTo("#s4"); $("#s4").css("marginLeft","-300px"); }); }); }); 左まわり?はできるんですが、逆方向がどうしてもできません。 animate({marginLeft:parseInt($("#s4").css("marginLeft"))+200+"px"},"slow","swing", のぶぶんが実はよくわかってません。 +200+"px"の部分は回転させる方向なわけですが だとすると、ある特定の位置までいったらappendなりprependがかかって 画像がお尻?につくという事なわけですが 逆方向はそうはならない。なぜなんだろうと納得できないわけです。 すいません。お願いします

  • jQuery クリックした後の動き

    ボタン(#btn)をクリックすると、#navWarpを右に200px 移動するところまでは出来ましたが、2度目のクリックで元の位置まで 戻すにはどのような方法があるのでしょうか。 宜しくお願いします。 ■jquery $(function(){ $("#btn").click(function(){ $("#navWarp").stop().animate({"left":"200px"},500); }); }); ■css #navWarp{ position:relative; margin:0 0 0 -200px; } #btn{ position:absolute; top:0; left:200px; cursor: pointer; } ■html <div id="navWarp"> <div id="btn"></div> </div>

  • jQueryで追加した要素がマウスホバーに反応しない

    jQueryを使って、ボタンを押すと要素を追加しています。 後から追加された要素はマウスホバーなどが有効にならないのですが、 対象方法などあるでしょうか。 下記のようなソースで質問の状態になります。 よろしくお願いします。 <html> <head> <title>test</title> <script type="text/javascript" src="system/jquery-1.3.2.min.js"></script> <script type="text/javascript"> <!-- jQuery(document).ready(function($){ jQuery(".edit").hover( function () { jQuery(this).css("background","yellow"); }, function () { jQuery(this).css("background","none"); } ); jQuery(".insert").click(function () { var html = "<div class='edit'><p>add-text</p></div>"; jQuery("#sortable .edit:first").before(html); }); }); // --> </script> </head> <body> <div><INPUT class="insert" type="button" value=INSERT></DIV> <div id="sortable" style="width:200px;"> <div class="edit"> <p>text1</p> </div> <div class="edit"> <p>text2</p> </div> <div class="edit"> <p>text3</p> </div> </div><!-- id="sortable" --> </body> </html>