質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

783閲覧

JavaScriptで通し番号を用いた処理をしたい

taroyama_taro

総合スコア7

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2023/01/10 06:33

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • それぞれ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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんな感じで

javascript

1<script> 2document.addEventListener('DOMContentLoaded',()=>{ 3 [...document.querySelectorAll('.test')].forEach((x,y)=>{ 4 x.id=`test_${y}`; 5 x.addEventListener('click',()=>{ 6 console.log(y); 7 }); 8 }); 9}); 10</script> 11<div class="test">a</div> 12<div class="test">b</div> 13<div class="test">c</div> 14<div class="test">d</div> 15<div class="test">e</div>

元ソースを活かすのであればwhileではなくforでまわすとか

javascript

1document.addEventListener('DOMContentLoaded', function(){ 2 const testObjects = document.getElementsByClassName('test'); 3 for(let i=0;i<testObjects.length;i++){ 4 testObjects[i].setAttribute('id', `test_${i}`); 5 testObjects[i].addEventListener('click', function(){ 6 console.log(i); 7 }); 8 }; 9});

投稿2023/01/10 07:06

編集2023/01/10 07:18
yambejp

総合スコア114843

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taroyama_taro

2023/01/10 07:31

繰り返し処理の外でiを定義するのが綺麗でない(というか元凶となっている)のですね、勉強になりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問