68687

[code]

    const hints = [
        "ロシア連邦",
        "ほうれん草",
        "７９kcal",
        "炒める"
    ];
    
[/code]

これらを、window.alertで表示させようとして以下のコードを書きました。

[code]

    const $button = document.getElementsByTagName("button");
    
    $button[0].addEventListener("click", ()=>{
      window.alert($button[0].textContent = hints[0]);
    });
    $button[1].addEventListener("click", ()=>{
      window.alert($button[1].textContent = hints[1]);
    });
    $button[2].addEventListener("click", ()=>{
      window.alert($button[2].textContent = hints[2]);
    });
    $button[3].addEventListener("click", ()=>{
      window.alert($button[3].textContent = hints[3]);
    });
    
[/code]

このコードをwhile文でループさせてリファクタリングをしようと以下のコードを書き込みました。

[code]

    let hintsIndex = 0;
    let hintsLength = $button.length;
    
    while (hintsIndex < hintsLength) {
      $button[hintsIndex].addEventListener("click", ()=>{
        window.alert($button[hintsIndex].textContent = hints[hintsIndex]);
      });
      hintsIndex++;
    };
    
[/code]

リファクタリング前のコードだと正常に機能するのですが、後者のコードではボタンをクリックしてもwindow.alertが出ず、無反応です。  
どのようにすれば正常にWindow.alertが出るようになるのでしょうか。お教えいただけると幸いです。


CC BY-SA 4.0
2020-07-18T03:14:23.050
68686
2020-07-22T12:23:51.587
2020-07-18T06:12:58.387
3060
41133
question
javascript
JavaScript のリファクタリングがうまくできません


こんにちははじめまして  
確認させていただきました。

まず **addEventListener**
したイベントリスナーですが、これはボタンがクリックされた時に動作するものです。当然ですがループを抜ける前にボタンが押されることはありません。ですので、修正後の例では。
**hintsIndex** にこの場合は常に4が入力されています。これでは、配列の長さをオーバーしてますのでundefinedとなり正常に動きません。

ではどうすればいいかですが、とりあえずは、 **addEventListener**
する前にその中で必要なものをbuttonオブジェクトに格納してしまえばどうでしょうか? これなら参照することに問題はありません。

また、addEventListnerを使ってるのですから、引数eventからボタンオブジェクトを取得しましょう。

[code]

    var hintsIndex = 0;
    let hintsLength = $button.length;
    
    while (hintsIndex < hintsLength) {
      $button[hintsIndex].hint = hints[hintsIndex];
      $button[hintsIndex].addEventListener("click", (event)=>{
            window.alert(event.target.textContent = event.target.hint);
        });
        hintsIndex++;
    };
    
[/code]

修正した結果は上記のとおりになります。比較してみてください。

<https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener>


CC BY-SA 4.0
2020-07-18T04:17:15.510
68687
2020-07-18T04:32:59.703
2020-07-18T04:32:59.703
37777
37777
68686
answer


このようにすれば alert 表示されるようになると思います。  
リファクタリングとして `$button` という変数は複数形の `$buttons` に改名しています。

[code]

    const $buttons = document.getElementsByTagName('button');
    hints.forEach((hint, i) => {
      $buttons[i].textContent = hint;
      window.alert($buttons[i].textContent);
    });
    
[/code]


CC BY-SA 4.0
2020-07-22T12:23:51.587
68834
2020-07-22T12:23:51.587
4388
68686
answer