LoginSignup
TP78
@TP78 (T P)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

JavaScript:指定した要素の文字列1文字ずつに対し、一定間隔でclassを付与したい。

解決したいこと

取得した4つの要素内の文字列1文字ずつにすべて同じclassを付与したいです。
(最終的にはclassにアニメーションを適用し動きをつけたい)

目指した方法は以下の通りです。
①取得する4つの要素に対して同一のclassを付与し、querySelectorAllで取得
②td内の文字列を1文字ずつspanタグで囲む
③spanタグに対して一定間隔でclassを付与
④新たに付与したclassにCSSでアニメーションを適用(ここはコードを割愛)

発生している問題・エラー

動きがつく以前に、文字列(★マーク)が表示すらされない状況です。

下記エラーメッセージが表示されています。
Uncaught TypeError: str is not iterable
at wrapCharSpan
at showStar

該当するソースコード

-HTML-

<table>
 <tr><td>評価1</td><td class='star'>★★★★★</td></tr>
 <tr><td>評価2</td><td class='star'>★★★★★</td></tr>
 <tr><td>評価3</td><td class='star'>★★★★★</td></tr>
 <tr><td>評価4</td><td class='star'>★★★★★</td></tr>
</table>


-JavaScript-
function showStar() {
  const wrapCharSpan = function(str) {
    return [...str].map(char => `<span>${char}</span>`).join('');
  }
    
  const spanText = document.querySelectorAll('.star');
  spanText.innerHTML = wrapCharSpan(spanText.textContent)
    
  Array.from(spanText.children).forEach((char, index) =>{
    window.setTimeout(function () {
      char.classList.add('show');
    }, 40 * index);
  });
}

自分で試したこと

以下の方法で実現したい動きは実装できましたが、もっと簡潔にできるのではと感じ、質問させていただきました。
・元々付与しているclassをstar1,star2...と分けて、それぞれquerySelectorで取得し上記の関数式を4つ書く

0

1Answer

document.querySelectorAll('.star') が返すのは NodeList (要素のリストを表すオブジェクト)であり、 .innerHTML プロパティは持っていません。 forEach で要素を1つずつ取り出して処理してください。

document.querySelectorAll('.star').forEach(spanText => {
  spanText.innerHTML = wrapCharSpan(spanText.textContent)
  Array.from(spanText.children).forEach((char, index) => {  })
})
1

Comments

  1. @TP78

    Questioner
    ご回答ありがとうございます!
    アドバイス通り修正したところ解決しました。

    基礎的な部分ですが、Nodeの理解が浅かったので今一度勉強します。

Your answer might help someone💌