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

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

新規登録して質問してみよう
ただいま回答率
85.50%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

Q&A

解決済

4回答

397閲覧

関数の引数としてループ変数を用いるときにのトラブル

Truphi

総合スコア13

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

0グッド

0クリップ

投稿2018/06/03 11:26

前提・実現したいこと

以下のコードにて、関数の引数にループ変数を用いたとき,意図した結果が得られず困っています。

発生している問題・エラーメッセージ

ボタン0、ボタン1、ボタン2のどのボタンをクリックしてもconsole.log(son)の結果「3」のみが出力されます。「ボタン0」がクリックされたときに「0」を、「ボタン1」をクリックしたときに「1」が出力されるというふうにしたいと考えています。

該当のソースコード

<body> <div id="id"></div> <script> function father(son){ console.log(son); }; for (var i=0;i<3;i++){ var div_element = document.createElement("div"); div_element.innerHTML = '<input id="sv" type="button" value="ボタン'+i+'" onclick="father(i)">'; var obj = document.getElementById("id"); obj.appendChild(div_element); }; </script> </body>

試したこと

ループ変数をその他グローバル変数に代入して,そのグローバル変数を引数として用いたりしましたが同様の結果が得られました。
初心者なので単純なことで躓いているのだとは思いますが,どうか対策をご教授いただければと思います。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答4

0

JavaScript

1div_element.innerHTML = '<input id="sv" type="button" value="ボタン'+i+'" onclick="father(i)">';

father() が呼び出された時点のグローバル変数 i の値を考えれば原因が分かります。
innerHTML に代入される文字列が何か、をコンソールに出力してみるといいでしょう。
そうすれば、「ボタン」と同じ方法で問題を回避できることに気が付きます。

分からない範囲が広い場合

分からない範囲が広い場合は、シンプルな問題に落とし込むことで理解できる事があります。
例えば、for文をなくして

JavaScript

1document.getElementById("id").innerHTML = '<input onclick="father(i)">';

とか、innerHTMLも排除して、

HTML

1<input onclick="father(i)">

と書いてみるとか。
そして、分からない部分を限定し、その分からない場所一つ以外は絶対の自信を持って理解できると断言出来るところまで落とし込んでください。
https://teratail.com/help/question-tips#questionTips2

Re: Truphi さん

投稿2018/06/03 11:33

編集2018/06/04 13:13
think49

総合スコア18156

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

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

Truphi

2018/06/03 12:08

ありがとうございます。 ”+変数+”の形で書かないといけない時がどのようなときであるかよくわからず困っています。加えて、ご教授いただければと思います。
think49

2018/06/03 13:37

> innerHTML に代入される文字列が何か、をコンソールに出力してみるといいでしょう。 こちらを試した結果はどうでしょう。 <input onclick="father(i)"> と <input onclick="father(2)"> の違いは分かりますか。
think49

2018/06/03 13:40

それから、繰り返しになりますが、father() が呼び出された時点のグローバル変数 i の値が何であると考えていますか。
Truphi

2018/06/03 14:11

申し訳ございません。「innerHTML に代入される文字列」の意味がよくわかりません。console.log(obj)のことでしょうか? ちなみにこの出力結果はどのボタンに関してもfather(i)の形で出力され,番号が繰り上がってないことが確認されています。 「<input onclick="father(i)"> と <input onclick="father(2)"> の違い」は,わかっていないかもしれません。(勿論違いはあると思いますが質問者様の意図が理解できていません) また,「father() が呼び出された時点のグローバル変数 i の値が何であると考えているか」に関してですがそこが理解できていません。どういうことでしょうか?何度も申し訳ありませんがよろしくお願いいたします。
think49

2018/06/04 13:19

親記事に追記しました。 正直なところ、「あれもこれもかも分かりません」状態では、「何なら分かっているのですか」と聞きたくなるのが回答者としての心情です。 こういう場合、かみ砕いた説明をして「理解できました」と返事を貰っても本当の意味で理解してないために同じような質問を繰り返すケースをたくさん経験しています。 まず、質問者さんの中で分かっている事と分からない事を切り分けるべきだと思います。 誤解を恐れずにいえば、かみ砕いた他人のレールの上の説明を読んで「分かったつもり」になるよりも、他人の説明から自分のレールを見つけて解を導き出す方が100倍良いです。
Truphi

2018/06/05 12:19

思いやりのあるご回答ありがとうございました。もっとわかりやすい質問ができるように自分自身を見なおし,精進したいと思います。ありがとうございました。
guest

0

div_element.innerHTML = '<input id="sv" type="button" value="ボタン'+i+'" onclick="father('+i+')">';
では?

id="sv"のタグが複数個出来るので、そこも修正する必要があります。

投稿2018/06/03 11:36

otn

総合スコア84423

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

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

Truphi

2018/06/03 12:05

無事できました!!!ありがとうございます。 追加で申し訳ないのですが,'+変数+' の形をどういうところで使用すべきかはっきりと理解できていません。文字+変数になったときのみ使用する必要があるものかと思っていました。参考サイト等でも構いませんので,追加でご教授いただければと思います。
otn

2018/06/03 15:16

参考サイトというか、よく考えれば分かるレベルの話です。 自分が何をしたいのか考えれば自明。分からないというのは、自分が何をしたいのか分かっていないと言うことです。
guest

0

ベストアンサー

私なりに端的にまとめてみました。

  • father関数が呼ばれた時点ではすでにfor文のループ処理が完了していることになります。
  • ループ処理が完了した時点でiには3が代入されています。

上記2点をまとめると以下のようになると思います。

『ボタン押下でfather関数を呼び、father関数が参照する変数iには3が代入されているので、出力される値は3である。』

では、意図した結果にするにはどうすればいいか?
ということになります。

javascript

1'<input id="sv" type="button" value="ボタン'+i+'" onclick="father(i)">'

この書き方だと、father関数にiを渡してる事になっています。
html出力結果は

html

1<input id="sv" type="button" value="ボタン0" onclick="father(i)"> 2<input id="sv" type="button" value="ボタン1" onclick="father(i)"> 3<input id="sv" type="button" value="ボタン2" onclick="father(i)">

こうです。
確かにfather関数にiを渡しています。

そこで、既に皆さんがご回答されてる通りに書けばいいわけです。

javascript

1'<input id="sv" type="button" value="ボタン'+i+'" onclick="father('+i+')">'

こちらを分割してみました。
(1)

javascript

1'<input id="sv" type="button" value="ボタン'

↑ここまでが文字列。

(2)

javascript

1+i+

↑変数iです。その文字列と変数i+で連結。

(3)

javascript

1'" onclick="father('

↑ここも文字列。

(4)

javascript

1+i+

↑変数iです。その文字列と変数i+で連結。

(5)

javascript

1')">'

この時のhtml出力結果は

html

1<input id="sv" type="button" value="ボタン0" onclick="father(0)"> 2<input id="sv" type="button" value="ボタン1" onclick="father(1)"> 3<input id="sv" type="button" value="ボタン2" onclick="father(2)">

結果としてfather関数には数値を渡してあげる必要があるので、ループ処理の中で数値を渡してあげるべく、文字列と変数を+で連結してあげる必要がある。
という事が言えると思います。

長くなってしまいましたが、参考になれば幸いです。

投稿2018/06/04 04:16

souta-haruran

総合スコア88

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

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

Truphi

2018/06/05 12:17

丁寧なご回答ありがとうございます。おかげさまで理解できました。
guest

0

質問を読み間違っていました、以下は関係ないです。


(編集前の回答↓)

js

1 for (var i=0;i<3;i++){ 2// ↓ 3 for (let i=0;i<3;i++){

投稿2018/06/03 11:33

編集2018/06/03 11:40
kei344

総合スコア69364

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

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

kei344

2018/06/03 11:38

あ、関係なかった。
Truphi

2018/06/03 11:52

勘違い起こさせて申し訳ございません。letについて勉強になりました。
mpyw

2018/06/03 16:57

タイトルと最初の数行流し読みして「絶対変数束縛の問題だ」と思って確信しつつ既存回答読んでいったら違った…w やはりみんな考えることは同じ…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問