TransWikia.com

JavaScript のリファクタリングがうまくできません

スタック・オーバーフロー Asked on September 1, 2021

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

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

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]);
});

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

let hintsIndex = 0;
let hintsLength = $button.length;

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

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

2 Answers

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

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

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

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

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++;
};

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

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

Correct answer by Kouki.W on September 1, 2021

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

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

Answered by urin on September 1, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP