• ベストアンサー

addEventListenerで

window.addEventListener("load", addEvents, false); function addEvents() {  for (var i = 0; i < 3; i++) {   document.getElementById("hoge" + i).addEventListener("click", function() { check(i) }, false);  } } ---- というコードで、イベントを追加したのですが hoge0をクリック -> check(3)を呼び出し hoge1をクリック -> check(3)を呼び出し hoge2をクリック -> check(3)を呼び出し となってしまいます。つまり、引数にループの最後の数字+1が渡されてしまいます。 どうしたらよいのでしょうか?

noname#108740
noname#108740

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

  • ベストアンサー
回答No.1

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Q3843076 TestCase 1</title> <script type="text/javascript"> //<![CDATA[ //addEventListenerを使っているのは意図的だね?(IEを考えなくていいよね?) //俺は不勉強で,あまり理解していない。 //一応関数コンストラクタでやるとうまく行くようだ。 //あとは・・・そうだな。iを利用するのを諦めて //this.getAttribute("id")とか(ぉ window.addEventListener("load", addEvents, false); function addEvents() { for (var i = 0; i < 3; i++) { document.getElementById("hoge" + i).addEventListener("click", new Function("alert(" + i.toString()+")"), false); } } //]]> </script> </head> <body> <p id="hoge0">あ</p> <p id="hoge1">あ</p> <p id="hoge2">あ</p> </body> </html>

noname#108740
質問者

お礼

Functionコンストラクタという手があったのですね・・・ すっかりその存在を忘れてました(笑) 回答ありがとうございました。

その他の回答 (2)

  • auty
  • ベストアンサー率58% (284/486)
回答No.3

himajin100000 さんのを見ずに投稿しました。 Functionコンストラクタの場合、指摘どおり動作するのを確認しました。 getAttribute("id")を使えば、 function() { var ss=this.getAttribute("id"); check(ss.substring(ss.length-1)); } ということですね。

  • auty
  • ベストアンサー率58% (284/486)
回答No.2

詳しくチェックしたわけではありませんが、 登録されたイベントハンドラは、実行するたびに評価されるようです。 したがって、この場合    i=3 として実行されるようです。 これは、    function() { check(i) } を    function() { check(i++) } としてみるとよく分かります。 実行するたびに1づつ増えていきます。 今回は、1づつ書かざるを得ないでしょう。 -----------------------------------------------------------------------------------------------   document.getElementById("hoge0").addEventListener("click", function() { check(0) }, false);   document.getElementById("hoge1").addEventListener("click", function() { check(1) }, false);   document.getElementById("hoge2").addEventListener("click", function() { check(2) }, false);

noname#108740
質問者

お礼

やはりそうだったんですね。 回答ありがとうございました。

関連するQ&A

  • イベントリスナーの部分を関数にしたい

    イベントリスナーの部分で、「load」以外に「change」も必要になったので関数にしたいのですが、 引数の関数の指定方法がわかりません。 どうすればいいのでしょうか。よろしくお願いします。 【イベントリスナーを関数にする前】 function hoge(){ this.view = function(){ var _this = this; window.addEventListener( 'load',function(){ _this.foo()}, false ); } this.foo =function(){ var txt = document.createTextNode( this.moji ); document.body.appendChild( txt ); } } var a =new hoge(); a.moji="テスト"; a.view(); 【やってみたこと】 function hoge(){ this.view = function(){ var _this = this; var func = function(){ _this.foo()}; this.addListener( 'window', 'load', func ); } this.addListener = function(elem,type,func){ elem.addEventListener( type,func, false ); } this.foo =function(){ var txt = document.createTextNode( this.moji ); document.body.appendChild( txt ); } } var a =new hoge(); a.moji="テスト"; a.view();

  • イベントリスナーで読み込んだ後に、DOMで文字を表

    イベントリスナーで読み込んだ後に、DOMで文字を表示させたい。 DOMを使って、文字を表示させるならイベントリスナーで読み込み必要があると思いました。 そこで、下記のように書いて試してみました。 function hoge(){ this.view = function(){ window.addEventListener( 'load',this.foo, false ); } this.foo =function(){ var txt = document.createTextNode( this.moji ); document.body.appendChild( txt ); } } var a =new hoge(); a.moji="テスト"; a.view(); すると、「undefined」と表示されます。 どうすればいいのでしょうか。よろしくお願いします。

  • iがクリックごとに増えるようにしたい

    二度目からはvar i = 0;を行わずにiがクリックごとに増えるようにしたいのですが、うまくいきません var firstClick = true; const startBtn = document.getElementById('js'); startBtn.addEventListener('click', ()=> { if(firstClick) { var i = 0; firstClick = false; } ~ stageNumDefault の二度目クリック時に数値が増えていかずNaNになってしまいます。 https://codepen.io/anon/pen/VbPpby に再現しておきました。

  • ループ内のaddeventlistner

    javascript初心者です、いろいろ検索したのですがわからず 教えてください。 サンプル <div id="hoge"></div> <script type=application/javascript> window.onload=function () { var html="検索エンジンのビッグ3" var big3= [ { "name":"google", "url":"http://google.com" }, { "name":"yahoo!", "url":"http://yahoo.com" }, { "name":"bing", "url":"http://bing.com" } ]; for (var i = 0, len = big3.length; i < len; i++) { html+= "<br />名前:"+big3[i].name+"<br />";  html+= "URL:"+big3[i].url+"<br />"; html+= '<input type="button" id="btn" value="投票" /><br />' }; document.getElementById("hoge").innerHTML=html; } </script> ----サンプルここまで このように配列をずらずらっと表示させてそれぞれのボタンを押すと、 その時の配列の情報を参照したいのです。 下のコードをボタンのすぐ下に置きましたが、cannot call method addEventListener of nullってエラーでできず、for文の外だと配列情報がとれず、基礎がわかっておらずすみませんが教えてください。 document.getElementById("btn").addEventListener('click',function(){alert("あなたがおしたのは"+big3[i].name)},false);

  • グローバル変数以外も変数は残り続ける?

    https://okwave.jp/qa/q9323518.html の続き var stoppingNow = false; がグローバル変数になっていないので仕様上はページ読み込み時に実行されて処理が終わった瞬間に この変数は削除されて使えなくなると聞いたのですが、 なぜかpauseBtnを押した後に、playBtnを押すと問題なく使えてしまいます。 グローバルにない変数は、stoppingNow = true;を実行してもそんな変数もうないとなるはずなのですよね? それともグローバルにない変数も残っていて、代入の処理よりも上、ないしは親のスコープにあれば使えるのが仕様なのですか? (function () { var stoppingNow = false; var pauseBtn = document.getElementById('js-pause-btn'); pauseBtn.addEventListener('click', function () { clearTimeout(it); stoppingNow = true; }); var playBtn = document.getElementById('js-play-btn'); playBtn.addEventListener('click', function () { if (stoppingNow === true) { iterative(); stoppingNow = false; } }); } myChange(); })();

  • イベントリスナーに設定した関数内で、id属性の値を取得するには

    IEでイベントリスナーに設定した関数で、イベントを発生させた要素のid属性値を取得する方法が分からずに困っています。 記述したコードは下記のようになります。Firefoxではうまく動作しました。 clickHandler内でFirefoxのe.currentTarget.idに対応するような処理はどのように行えばよいでしょうか。 ------------ JavaScript部分 ----------------------- function addEvent(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture); return true; } else if (elm.attachEvent) { var r = elm.attachEvent('on' + evType, fn); return r; } else { elm['on' + evType] = fn; } } function clickHandler(e) { var id; if (document.all && !window.opera) { // IEの場合に、ここの処理でid属性の属性地 hoge1やhoge2を取得したい。 // id = window.event.srcElement.id; これではだめ } else { id = e.currentTarget.id; } // idに応じた処理 } var elm1 = document.getElementById('hoge1'); var elm1 = document.getElementById('hoge2'); addEvent(elm1,'click',clickHandler,false); addEvent(elm2,'click',clickHandler,false); ------------ HTML部分 ----------------------- <li><a id="hoge1" href="#"><img src="●●" /></a></li> <li><a id="hoge2" href="#"><img src="●●" /></a></li> 先に進むことができずに困っています。よろしくお願いします。

  • event量産

    はじめまして! さっそくですが以下を <script type="text/javascript"> function $(e) { return document.getElementById(e); } function $$(n) { return $(n).childNodes[0].href; } function lh(u) { top.location.href = $$(u); } function addevent(node,evt,func){ if(node.addEventListener){ node.addEventListener(evt,func,false); } else if(node.attachEvent){ node.attachEvent("on"+evt,func); } } addevent( window,"load", function(){ //↓ここからが質問です addevent($("css_link"), "click", function(){ lh("css_link"); }); //↑これがうまくいったので var doo = "other_link"; addevent($(doo), "click", function(){ lh(doo); }); //↑次に向けてのテスト これもうまくいきました for(i=1;i<20;i++) { var names = "page"+i; addevent($(names), "click", function(){ lh(names); }); } //↑しかしこれがうまくいかない } ); </script> やっていることは<DIV>の中にある<A>のhref内容を読み取り、<DIV>と<A>の隙間をクリックしても同じURLにジャンプさせたいということです。 上記の"css_link"や"other_link"などの固定URLは羅列するつもりです。 これは問題なく動作します。 問題の ループさせている部分は"page1"~"page19"まで可変でPHPで書き出す部分です。 この部分の処理方法を教えてください。 もうひとつ質問です とりあえず19回ループさせていますが、ページ内に存在しないidを指定しても(実際はpage1,page2だけとか)現在はエラーにならないようですが、問題点などありましたら教えてください。 よろしくお願いします!

  • JavaScript IDの複数読み込みについて

    JavaScript(プログラミング)はほとんど知識のないもので、 自分なりに調べたのですが、分からないので質問させていただきます。 下記のようなJavaScriptがあります。 window.onload = function() { var target = document.getElementById("●●"); target.addEventListener("touchstart", function(){this.className="touchstyle";}, false); target.addEventListener("touchend", function(){this.className="notouchstyle";}, false); } "●●"のほかに"▲▲" "■■"というIDを読み込ませたいのですが、 それは可能でしょうか。 ("xxx"はclass指定に変更でも構いません) 色々と試してみたのですが、うまくいかず困っております。 何卒ご教授のほど宜しくお願い致します。

  • window.onloadでのfunction

    javascript初心者で質問自身が僕が解決したい問題の原因かどうかも解らずに質問しています。 <script type="text/javascript"> <!-- function hoge_1() { ~処理1~ } function hoge_2(hiki_suu) { ~処理2~ } window.onload = function() { document.getElementById("button_1").onclock = hoge_1; document.getElementById("button_2").onclock = hoge_2("watasu"); } // --> </script> 上記のようにページheadにscriptを配置したとします。ページ上のbutton_1がクリックされると処理1が実行されるのですが、hoge_2のように引数を使ってしまうと、onload時に処理2を実行してしまい、button_2は有効に動作しません。 functionの引数の問題なのか、window.onloadの作法なのか、なにが悪いのか全く解らず質問しています。 ご指導のほどよろしくお願いいたします。

  • 複数のイベントリスナーを設置するのは正しい?

    クリック時、マウスオーバー時、マウスアウト時の処理を作るとき、 イベントリスナーの使い方はこのようなやり方でよいでしょうか。 var d = document.getElement.ById("id"); d.addEventListener('click', function(e){ var tar=e.target; tar.style.backgroundColor ="#000000"; },false); d.addEventListener('mouseover', function(e){ var tar=e.target; tar.style.backgroundColor ="#aaaaaa"; },false); d.addEventListener('mouseout', function(e){ var tar=e.target; tar.style.backgroundColor ="#555555"; },false);