実現したいこと
ここに実現したいことを箇条書きで書いてください。
- それぞれ0〜4を表示するdiv要素に対し、順に0〜4のidを付与し、クリックされた要素のidと同じ数字をコンソール上に出力するイベントをセットしたい
- div要素の数は固定ではないためwhileを用いたい
- div要素に表示される文字は固定ではないため、表示されている文字列を利用して処理することはできない
- ビューファイルの当該箇所は下記の通り
erb
1<% 5.times do |i| %> 2 <%= tag.div(i, class: 'test') %> 3<% end %>
該当のソースコードと発生している問題
javascript
1document.addEventListener('DOMContentLoaded', function(){ 2 // テストオブジェクトを取得 3 const testObjects = document.getElementsByClassName('test'); 4 // テストオブジェクトが存在しなければ終了 5 if (!testObjects) return null; 6 7 const max = testObjects.length; 8 let i = 0; 9 while (i < max) { 10 11 testObjects[`${i}`].setAttribute('id', `test_${i}`); 12 const testObject = document.getElementById(`test_${i}`); 13 testObject.addEventListener('click', function(){ 14 console.log(`${i}`); 15 }); 16 i++; 17 }; 18});
参照されるJavaScriptファイルを上のように記述したところ、idは順に0〜4が付与されたものの、どの要素をクリックしてもコンソール上には"5"と出力されてしまう。繰り返し処理のためにletで定義された変数は、呼び出し(ここでは14行目のイベント)のたびに再計算されるものと思い、下のように編集した。
試したこと
javascript
1document.addEventListener('DOMContentLoaded', function(){ 2 // テストオブジェクトを取得 3 const testObjects = document.getElementsByClassName('test'); 4 // テストオブジェクトが存在しなければ終了 5 if (!testObjects) return null; 6 7 const max = testObjects.length; 8 let i = 0; 9 while (i < max) { 10 const iFixed = i; 11 testObjects[`${i}`].setAttribute('id', `test_${i}`); 12 const testObject = document.getElementById(`test_${i}`); 13 testObject.addEventListener('click', function(){ 14 console.log(`${iFixed}`); 15 }); 16 i++; 17 }; 18});
10行目に
javascript
1 const iFixed = i;
を挿入し、14行目を編集した。
javascript
1 // 編集前 2 console.log(`${i}`); 3 // 編集後 4 console.log(`${iFixed}`);
これによって意図する挙動を確認できましたが、これが連続する要素にそれぞれイベントをセットするための正攻法なのかわかりません。より一般的、スマートな方法があればご教示ください。
よろしくお願いいたします。
補足情報(FW/ツールのバージョンなど)
Ruby:2.6.5
Ruby on Rails:6.0.6
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/01/10 07:31