-PR-
締切り
済み

ループ内のaddeventlistner

  • 困ってます
  • 質問No.6940282
  • 閲覧数329
  • ありがとう数3
  • 気になる数0
  • 回答数8
  • コメント数0

お礼率 33% (3/9)

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);
通報する
  • 回答数8
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

回答 (全8件)

  • 回答No.3
レベル12

ベストアンサー率 48% (232/481)

len 推進派(?)の者です。 やっぱり、それひつようでしょ! (というか、へんすうにつかわれるなまえは、おおもじ派。) 文字列の連結は、配列にして一気に連結する派(?)。 バブリングするイベントは、document で監視する派(?)。 <!DOCTYPE html> <html lang="ja">  <head>   <meta c ...続きを読む
len 推進派(?)の者です。
やっぱり、それひつようでしょ!
(というか、へんすうにつかわれるなまえは、おおもじ派。)

文字列の連結は、配列にして一気に連結する派(?)。

バブリングするイベントは、document で監視する派(?)。

<!DOCTYPE html>
<html lang="ja">
 <head>
  <meta charset="utf-8" />
  <title>test</title>
 </head>
 <body>
  <div id="hoge"></div>
  <script type="text/javascript">

var big3 = [
 { "name": "google", "url": "http://google.com" },
 { "name": "yahoo!", "url": "http://yahoo.com" },
 { "name": "bing", "url": "http://bing.com" }
];

var html = ["検索エンジンのビッグ3"];

for (var i = 0, I = big3.length; i < I; i++) {
 html.push ('名前:' + big3[i].name);
 html.push ('URL:' + big3[i].url);
 html.push ('<input type="button" id="btn' + i + '" value="投票" />');
}
document.getElementById ("hoge").innerHTML = html.join ('<br />');


function handler (event) {
 var e = event.target || event.srcElement;
 var n, c;
 
 if ('INPUT' === e.nodeName)
  if ('button' === e.type)
   if ('投票' === e.value)
    if (c = e.id.match (/^btn(\d+)$/))
     alert (big3[ Number (c[1]) ].name);
}

document./*@if (1)
 attachEvent ('on'+ @else@*/
 addEventListener (/*@end@*/
  'click', handler, false);

  </script>
 </body>
</html>

で、ほそくをみたら、Chrome13か~
addEventListenerには、おぶじぇくとをわたすことができるよ。
ついでに、いべんとはんどらーも、おぶじぇくとのなかに、かいちゃえ~!

<!DOCTYPE html>
<html lang="ja">
 <head>
  <meta charset="utf-8" />
  <title>test</title>
 </head>
 <body>
  <div id="hoge"></div>
  <script type="text/javascript">

var Big3 = {
 'member' :
  [
   { "name": "google", "url": "http://google.com" },
   { "name": "yahoo!", "url": "http://yahoo.com" },
   { "name": "bing", "url": "http://bing.com" }
  ],


 'handleEvent' :
  (function (event) {
   var e = event.target || event.srcElement;
   var n, c;
   
   if ('INPUT' === e.nodeName)
    if ('button' === e.type)
     if ('投票' === e.value)
      if (c = e.id.match (/^btn(\d+)$/))
       alert (this.member[ Number (c[1]) ].name);
  }),
 
 
 'demo' :
  (function (target) {
   var html = ["検索エンジンのビッグ3"];
   var m = this.member;
   var o;
   
   for (var i = 0; o = m[i]; i++) {
    html.push ('名前:' + o.name);
    html.push ('URL:' + o.url);
    html.push ('<input type="button" id="btn' + i + '" value="投票" />');
   }
   target.innerHTML = html.join ('<br />');

   target.ownerDocument.addEventListener ('click', this, false);
  })
};

Big3.demo (document.getElementById ('hoge'));

  </script>
 </body>
</html>

でもね、いいたかったのは、ほかにもある。
big3のられつは、あきらかにりすとこうぞうなのだから <br/>でこうせいされているのが、へん!
すくりぷとが、うごかないかんきょうのひとがみても、URLとかなまえとかさいていげんみられるようにしておくべきだよ。
すくりぷとは、そのりすとこうぞうをかいせきしてうごかすべき。

onload も、すくりぷとをさいごにかくことによって、りようしない派、だった!
document にいべんとをはりつけておけば、innerHTMLでよみこんだものがあろうがなかろうがかきかえられようが、うごけるし、documentは、すべてよみこみがおわらなくても、そんざいしているだろうし。
お礼コメント
javab

お礼率 33% (3/9)

回答ありがとうございます!!

いつの間にやらいっぱい回答いただいてありがたいです。
初心者という免罪符が役に立たないことは重々承知してますが
リスト構造もハブリング?も理解していないのでいただいたサンプル元に
調べてみます。 @とか出てくるととたんにわからなくなる。。
投稿日時 - 2011-08-17 13:03:52
  • 回答No.2
レベル5

ベストアンサー率 75% (3/4)

>> 下のコードをボタンのすぐ下に置きましたが ... ボタンのすぐ下に置いたというのは、もとのコードはこうだったのでしょうか? html+= "<br />名前:"+big3[i].name+"<br />"; html+= "URL:"+big3[i].url+"<br /> ...続きを読む
>> 下のコードをボタンのすぐ下に置きましたが ...

ボタンのすぐ下に置いたというのは、もとのコードはこうだったのでしょうか?
html+= "<br />名前:"+big3[i].name+"<br />";
html+= "URL:"+big3[i].url+"<br />";
html+= '<input type="button" id="btn" value="投票" /><br />'
document.getElementById("btn").addEventListener('click',function(){alert("あなたがおしたのは"+big3[i].name)},false);
};

"cannot call method addEventListener of null"というエラーの意味は、nullオブジェクトに対してaddEventListener()メソッドの呼び出しを行なったけど、nullオブジェクトはそのメソッドを持っていなかったので失敗したということです。

推測で申し訳ないですが、もし上記のようなコードであった場合、document.getElementById('btn')がnullを返すのでこのエラーが発生します。この段階ではまだボタンは生成されていない(DOMツリーに加えられていない)ので対象のボタンを見つけ出そうとしても見つからないからです。

処理の流れとしては、
1.ボタンを生成する
2.ボタンにイベントハンドラを登録する
3.ボタンをDOMツリーに加える
という手順をふむ必要があります。2と3の順序は逆でもかまいません。

No1の方が示してくださっているコードを参考にいじってみると動作理解が深まるかと思います。
お礼コメント
javab

お礼率 33% (3/9)

ありがとうございます!
ブラウザはChrome13です、お二方の回答を元に調べて
進めてみます。
投稿日時 - 2011-08-14 14:50:46
  • 回答No.8
レベル12

ベストアンサー率 48% (232/481)

think49 さん、 ほそく、ありがとうございます。 >「Function#bind を使いましょー」 そそっ。 (document にぞくすまえに、いべんとをはりつけたから?) -- > 簡潔に書けたりします? う~ん、かんがえてたら、はたしてこれが「よいさんぷる」なのか?! (しつもんしゃを、おきざりにした感。ごめんなさい) <!DOCTYPE html> <ht ...続きを読む
think49 さん、

ほそく、ありがとうございます。
>「Function#bind を使いましょー」
そそっ。

(document にぞくすまえに、いべんとをはりつけたから?)

--
> 簡潔に書けたりします?
う~ん、かんがえてたら、はたしてこれが「よいさんぷる」なのか?!
(しつもんしゃを、おきざりにした感。ごめんなさい)
<!DOCTYPE html>
<html lang="ja">

<meta charset="utf-8" />
<title></title>

<body>
 <ol>
  <li>a
  <li>b
  <li>c
 </ol>
  
<script type="application/javascript; version=1.8">
var big3 =
 [
  { "name": "google", "url": "http://google.com" },
  { "name": "yahoo!", "url": "http://yahoo.com" },
  { "name": "bing", "url": "http://bing.com" }
 ];

var LI =
 document.querySelectorAll ('body > ol > li');

var func =
 (function (e) alert (big3[this].name));

Array.forEach (LI,
 (function (li, i)
  (li.addEventListener ('click', func.bind (i), false))));

/*
for (var i = 0, I = LI.length; i < I; i++)
 LI[i].addEventListener ('click', func.bind (i), false);
*/

</script>
  • 回答No.5
レベル12

ベストアンサー率 48% (232/481)

> 楽して目的を果たす なのに、jQuery のしつもんがおおいのは、なぜ?() jQuery は、さっぱりなものですから・・・ だまって、bind つかいましょ (笑);
> 楽して目的を果たす
なのに、jQuery のしつもんがおおいのは、なぜ?()
jQuery は、さっぱりなものですから・・・

だまって、bind つかいましょ (笑);
  • 回答No.6
レベル10

ベストアンサー率 59% (64/108)

jquery使うには、 javascriptが分かる必要がある。 ということですよね。。。 >だまって、bind つかいましょ (笑); ↑も、もしかしてもっと簡潔に書けたりします?(汗
jquery使うには、
javascriptが分かる必要がある。
ということですよね。。。

>だまって、bind つかいましょ (笑);
↑も、もしかしてもっと簡潔に書けたりします?(汗
  • 回答No.1
レベル12

ベストアンサー率 52% (203/388)

それっぽいサンプルを作ってみたので載せておきます。 #インデントは全角スペースになってますので注意 <!DOCTYPE html> <html lang="ja">  <head>   <meta charset="utf-8" />   <title>test</title>   <s ...続きを読む
それっぽいサンプルを作ってみたので載せておきます。
#インデントは全角スペースになってますので注意

<!DOCTYPE html>
<html lang="ja">
 <head>
  <meta charset="utf-8" />
  <title>test</title>
  <script type="text/javascript">
window.onload = function() {
 var big3 = [
  { "name": "google", "url": "http://google.com" },
  { "name": "yahoo!", "url": "http://yahoo.com" },
  { "name": "bing", "url": "http://bing.com" }
 ];

 // HTMLの生成
 var html = "検索エンジンのビッグ3";
 for (var i = 0; i < big3.length; i++) {
  html += "<br />名前:" + big3[i].name + "<br />";
  html += "URL:" + big3[i].url + "<br />";
  html += '<input type="button" id="btn' + i + '" value="投票" /><br />';
 };
 document.getElementById("hoge").innerHTML = html;
 
 // Eventの登録用クロージャ
 var onClick = function(i) {
  return function() { alert("あなたがおしたのは" + big3[i].name); }
 }
 // Eventの登録
 for (var i = 0; i < big3.length; i++) {
  var elem = document.getElementById("btn" + i);
  if (elem.attachEvent) {
   elem.attachEvent("onclick", onClick(i));
  } else {
   elem.addEventListener("click", onClick(i), false);
  }
 }
}
  </script>
 </head>
 <body>
  <div id="hoge"></div>
 </body>
</html>

以下、何点か補足。

■len?
>for (var i = 0, len = big3.length; i < len; i++) {
このlenは特に意味が無い気がします。
普通に
for (var i = 0; i < big3.length; i++) {
すればよいかと。

■HTMLのid
>html+= '<input type="button" id="btn" value="投票" /><br />'
idの値はHTML内で一意でなくてはなりません。classを使う方がスマートな気がしますが、サンプルでは数値を付加することにしてみました。
http://www.tohoho-web.com/html/attr/id.htm

■ブラウザ固有の問題
>cannot call method addEventListener of nullってエラーでできず、
ブラウザとしてIEをお使いではないでしょうか?
IE8以下ではイベントを登録するのにattachEventを使用する必要があります。
https://developer.mozilla.org/ja/DOM/element.addEventListener#Internet_Explorer
http://journal.mycom.co.jp/news/2010/03/31/032/index.html

この手のブラウザ固有の問題はたくさんありますので要注意です。
http://gihyo.jp/dev/serial/01/crossbrowser-javascript/0001
それと、
><script type=application/javascript>
についても、現状<script type="text/javascript">が無難かと思います。
http://ie-style.blogspot.com/2010/03/ie9-javascript-mime.html

■クロージャ
上記ソースではonClick(i)の部分に直接function(){alert("あなたがおしたのは"+big3[i].name)}と入れればいいじゃないかと思われるかもしれませんが、このiはfor文のiの参照です。よって、どのボタンのクリックイベントで呼ばれたときも、このケースではfor文終了時のi=3が参照されます。
それではまずいので、今回はクロージャを利用してみました。
#クロージャとは:http://dqn.sakusakutto.jp/2009/01/javascript.html
関数への引数としてプリミティブ型を渡した場合、値渡しになるので、それを利用しています。
型について:http://www.findxfine.com/index.php?p=228
クロージャの他にもinput要素のプロパティを利用する方法などもあるかと思います。


以上です。
少し難しい内容が入っていますが頑張ってください。
お礼コメント
javab

お礼率 33% (3/9)

ありがとうございます!

ご紹介いただいたURLを参考にして作ってみます。
クロージャが全く理解できてませんので。。
投稿日時 - 2011-08-14 14:49:47
  • 回答No.7
レベル12

ベストアンサー率 59% (283/479)

jQuery ならこんな感じでしょうか。 http://jsfiddle.net/WVyAr/ バブリングを利用する方がスマートだと思いますが、それ以前にHTMLにもデータを置くなら配列ではなくDOMノードを参照する方がスマートって気がしないでもありません。 <span class="site-name"> のように参照しやすくするとかdata-*属性とかNode#setU ...続きを読む
jQuery ならこんな感じでしょうか。
http://jsfiddle.net/WVyAr/
バブリングを利用する方がスマートだと思いますが、それ以前にHTMLにもデータを置くなら配列ではなくDOMノードを参照する方がスマートって気がしないでもありません。
<span class="site-name"> のように参照しやすくするとかdata-*属性とかNode#setUserDataとか。

To: #4, 6 さん
横からですが、#4 さんのコードはクロスページリークするんじゃないでしょうか?
http://msdn.microsoft.com/ja-jp/library/bb250448%28v=vs.85%29.aspx
babu_baboo さんの指摘は「Function#bind を使いましょー」と読みましたが、よくよく調査してみると jQuery には Function#bind の代替がないっぽいです。(jQuery#bind は addEventListener のショートカットのようで)
今ケースでは jQuery.data() が使えそうですが、内部コードが頭を抱えたくなるコードなのでお勧めしがたかったり…。
http://api.jquery.com/jQuery.data/
  • 回答No.4
レベル10

ベストアンサー率 59% (64/108)

白熱してますね。すばらしい。 えーと私からは、楽して目的を果たす方法をご紹介します。 jquery.jsというありがたいjavascriptライブラリをうまく利用する方法です。 まぁ、こういう書き方もある、ということで、 頭の片隅に置いておいて下さい。 コピペで動きます。 ------------------- <!DOCTYPE html> <html> <head&g ...続きを読む
白熱してますね。すばらしい。

えーと私からは、楽して目的を果たす方法をご紹介します。
jquery.jsというありがたいjavascriptライブラリをうまく利用する方法です。

まぁ、こういう書き方もある、ということで、
頭の片隅に置いておいて下さい。
コピペで動きます。
-------------------
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">

var body = $('body');
var big3 = [
{
name:"google",
url:"http://google.com"
},
{
name:"yahoo!",
url:"http://yahoo.com"
},
{
name:"bing",
url:"http://bing.com"
}
];

for( var i = 0; i < big3.length; i++ )
{
var btn = $('<input type="button" value="' + big3[i].name + '">');
btn.click(function( e )
{
return function()
{
alert( big3[e.val].name );
}
}({ val : i }));

body.append( btn );
}

</script>
</body>
</html>
-------------------
※firefoxでしか確認してないです。
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ