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

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

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

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

Q&A

解決済

3回答

299閲覧

アラート関数の表示される値がliタグの番号とずれてしまう

begenner

総合スコア79

JavaScript

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

0グッド

0クリップ

投稿2019/04/02 07:37

jsの勉強をしていますがリスト項目のクリックした項目のliタグ中のテキストと数字を表示させるようにしたいのですがうまくいきません(m_ m)
わかる方がいらっしゃれば教えていただきますようよろしくお願いいたします(m
_m)

###エラー内容
エラー表示はなし

###期待する動作
html内のliタグのテキストと変数iの値がアラートで正しく表示されるようにしたい

###試したこと
li.addEventListner以降の部分を

js

1function(){ 2 3}())

で囲んでみましたがうまくいきませんでした(m_ _m)

###該当のソースコード

html

1 2<!DOCTYPE html> 3<html lang="ja"> 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 8 <title>Document</title> 9</head> 10<body> 11 <ul> 12 <li>one</li> 13 <li>two</li> 14 <li>three</li> 15 <li>four</li> 16 <li>five</li> 17 </ul> 18 19 <script type="text/javascript"> 20 var items = document.querySelectorAll('li') 21 22 for(var i = 0; i < 5; i++){ 23 var li = items[i] 24 25 // (アラート表示で常にfive:5が表示される) 26 li.addEventListener('click', function () { 27 alert(li.textContent + ':' + i) 28 }) 29 } 30 </script> 31 32</body> 33</html> 34

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

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

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

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

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

guest

回答3

0

ベストアンサー

function () { alert(li.textContent + ':' + i )}と関数を作った時点では、liiの値はまだ参照されません。この関数が実行されるときに初めて、liiの値が参照されます。

実際にこの関数が実行されるのはfor文が終わったあと、<li>がクリックされたときです。そのときのliiの値は何でしょうか?varで宣言された変数はfunction scopeですから、for文を通してliiという変数はそれぞれ1個しかありません。for文はi=5、li=5つ目の<li> になって終了しました。そのため、どれをクリックしてもfive:5がアラート表示されます。

これはES6というJSのバージョンで追加されたconstletを用いることで解決できます。constletで宣言された変数はblock scopeであり、そのブロック限定の変数となります。例えば下のようにブロック内で宣言された変数はその中でしか使えません。

js

1if (true) { 2 let x = 3 3} 4console.log(x) // Uncaught ReferenceError: x is not defined

同様に、while文やfor文内でlet/constで宣言すると、反復するごとに新しい変数が作られます。

kei344さんの回答のように、for(let i = 0; ...) { }letを用いて宣言すると**iという変数はループが反復するごとに作られます**。つまり、全体を通してi=0、i=1、i=2、i=3、i=4という別々の変数が作られます。最初の関数function () { alert(li.textContent + ':' + i )}はそれぞれ別のiを指すようになるため、クリックした<li>に対応するiが表示されるようになります。

liについても同様に、letあるいはconstで宣言することによって、反復するごとに新しい変数liが作られるようになるので、意図した動作になります。

Demo

参考
クロージャ - MDN

投稿2019/04/02 10:05

karamarimo

総合スコア2551

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

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

begenner

2019/04/02 14:05

とても詳しい解説ありがとうございます!! おかげさまでもやもやがスッキリしました!!
guest

0

javascript

1<script> 2window.addEventListener('DOMContentLoaded', function(e){ 3 [].forEach.call(document.querySelectorAll('li'),function(x,y){ 4 x.addEventListener('click', function (e) { 5 alert(x.textContent+':'+(y+1)); 6 }); 7 }); 8}); 9 10</script> 11<ul> 12 <li>one</li> 13 <li>two</li> 14 <li>three</li> 15 <li>four</li> 16 <li>five</li> 17</ul>

投稿2019/04/02 07:43

yambejp

総合スコア114779

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

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

begenner

2019/04/02 08:42

動作確認して問題なく動くことが確認できました!! jsに関してまだまだ初心者なので調べながら、参考にしてより理解を深めていきたいと思います!! 回答いただきありがとうございます!!
guest

0

js

1// for(var i = 0; i < 5; i++) 2// ↓ スコープの問題です。 3 for(let i = 0; i < 5; i++)

投稿2019/04/02 07:40

kei344

総合スコア69400

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

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

begenner

2019/04/02 09:18

動作確認して問題なく動くことが確認できました!! ありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問