いつもお世話になっています
Javascriptでのイベント処理にてわからないことがありましたので、質問させて頂きました
サムネイルの様に、複数枚並んだ画像全てにイベント処理を実装したく、下記のようなコードを記述しましたが、上手くいきませんでした(show関数が実行されなかったり、iが配列の最大値の時のみ実行されたりします)
この記述がなぜ上手くいかないのか、どうすれば上手くいくのかを、教えて頂ければと思います
お手数ですが、よろしくお願い申し上げます
lang
1// 関数定義 2function show(x){ 3 console.log(x); 4} 5 6// イベント処理 7var img = document.getElementsByTagName('img'); 8 9for(var i = 0; i < img.length; i++){ 10 img[i].onclick = function(){ 11 show(i); 12 }; 13}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
click
が呼び出された時点で呼び出される変数 i
が for
文を通過した後に参照される為ですね。
変数 i
を束縛する方法はいくつかありますが、handleEvent を使用する方法はどうでしょうか。
(JSFiddle にもサンプルをUPしました。)
HTML
1<img src="sample-1.jpg" alt="sample1"> 2<img src="sample-2.jpg" alt="sample2"> 3 4<script> 5(function () {i 6 function handleClick (event) { 7 console.log(this.x); 8 } 9 10 var imgs = document.getElementsByTagName('img'); 11 12 for (var i = 0, l = imgs.length; i < l; ++i) { 13 imgs[i].addEventListener('click', {x: i, handleEvent: handleClick}, false); 14 } 15}()); 16</script>
handleEvent
は addEventListener
に備わった機能なので第一引数の event
オブジェクトと併用できます。
(2015/09/08 19:14追記)
もし、IE8- にも対応させるならクロージャで変数束縛する方法があります。
(JSFiddleにサンプルUPしました。)
JavaScript
1(function () { 2 function createHandleClick (i) { 3 return function handleClick (event) { 4 console.log(i, event.type); 5 }; 6 } 7 8 function addEvent (element, type, listener) { 9 if (element.addEventListener) { 10 element.addEventListener(type, listener, false); 11 } else if (element.attachEvent) { 12 element.attachEvent('on' + type, listener); 13 } 14 } 15 16 function init () { 17 var imgs = document.getElementsByTagName('img'); 18 19 for (var i = 0, l = imgs.length; i < l; ++i) { 20 addEvent(imgs[i], 'click', createHandleClick(i)); 21 } 22 } 23 24 init(); 25}());
(2015/09/08 23:00追記)
data-* 属性で index を割り振っておくのも一つの手段だと思います。
(JSFiddleにサンプルUPしました)
HTML
1<img src="sample-1.jpg" alt="sample1" data-i="1"> 2<img src="sample-2.jpg" alt="sample2" data-i="2"> 3 4<script> 5(function () { 6 function handleClick (event) { 7 var img = event.target || event.srcElement; // target要素を得る(Standard || IE8-) 8 console.log(img.getAttribute('data-i'), event.type); // data-*属性を参照 9 } 10 11 function addEvent (element, type, listener) { 12 if (element.addEventListener) { // Standard 13 element.addEventListener(type, listener, false); 14 } else if (element.attachEvent) { // IE8- 15 element.attachEvent('on' + type, listener); 16 } 17 } 18 19 function init () { 20 var imgs = document.getElementsByTagName('img'); 21 22 for (var i = 0, l = imgs.length; i < l; ++i) { 23 addEvent(imgs[i], 'click', handleClick); 24 } 25 } 26 27 init(); 28}()); 29</script>
img要素の親要素ノードでバブリングを利用してキャプチャすると更にスマートになります。
投稿2015/09/08 07:50
編集2015/09/08 14:00総合スコア18162
0
どういう処理を行うかわかりませんが、
私なら次のように書きます。
ポイントは2つあるんですが、
1つ目は基本ですがimgタグの後にscriptタグを書く
2つ目はiの評価がクリック時に行われる書き方なのでbindでその時の値を渡しておく
って感じです。
それぞれshow関数が実行されない件と、iが配列の最大値で実行される件の対策です。
参考になると良いのですが。
<img src="image.jpg" width="20px"> <img src="image2.jpg" width="20px"> <script> // 関数定義 function show(x){ console.log(x); } // イベント処理 var img = document.getElementsByTagName('img'); for(var i = 0; i < img.length; i++){ img[i].onclick = show.bind(img[i], i) } </script>
投稿2015/09/08 07:24
総合スコア415
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/09/08 08:25
2015/09/08 08:45
2015/09/08 09:30
2015/09/08 09:58
退会済みユーザー
2015/09/08 13:39
2015/09/09 00:01
0
jQueryを使ったサンプルをあげます。
html
1<img class="thumbnail" src="image.jpg" width="20px"> 2<img class="thumbnail" src="image2.jpg" width="20px"> 3 4<script> 5$(document).ready(function(){ 6 // thumbnailクラスが付いているものすべてをjQueryオブジェクで取得 7 var $thumbnails = $('.thumbnail'); 8 9 // クリックイベントを定義 10 $thumbnails.on('click', function(e) { 11 // 実処理関数にjQueryオブジェクトで引き渡す 12 clickEvent($(this)); 13 }); 14 15 /** 16 * サムネイルクリックイベント 17 * param $n サムネイル画像タグのjQueryオブジェクト 18 * 19 **/ 20 var clickEvent = function($n) { 21 console.log($n.attr('src')); 22 }; 23}); 24</script>
コメントを充実させたので、少し長く見えますが、実コードはすごくシンプルになります。
jQueryの導入や賛否は置いておいて。。。。
投稿2015/09/08 09:01
総合スコア61
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/09/08 13:50
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/09/08 08:30
2015/09/08 08:40
退会済みユーザー
2015/09/08 13:10
2015/09/08 14:08