【jQuery】特定要素内のテキストを1文字ずつ扱おう【spanで囲む】

はじめに

はじめまして、NNCの中里です。
jQueryで「特定要素内のテキストを1文字ずつ扱いたいなぁ」と思う時ってよくありますよね。僕はあります。
でもHTML上で1文字ずつspanタグで囲むのはなんだか不格好だし、jQueryでできたらHTMLの記述もスマートで良いですよね。

今日はそれに挑戦したいと思います。
(今回の内容はやや中級者向けです)

完成イメージ

完成イメージは下のような動きです。
テキストを1文字ずつタイミングをずらしてアニメーションさせています。
このようなアニメーションの場合、それぞれのテキストを何かしらのタグで囲む必要があります。

実際のコード

<h1 class="head__design">HeadingDesign</h1>
body {
  background-color: #ffc;
}
h1 {
  font-size: 60px;
  display: flex;
  height: 90px;
  box-sizing: border-box;
}
h1 span {
  animation-name: textAnime;
  animation-duration: 1s;
  animation-timing-function: linear;
  animation-delay: 0s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  display: block;
}
@keyframes textAnime {
  0% {
    margin-top: 0;
  }
  100% {
    margin-top: -20px;
  }
}
$(function(){
  var head = $(".head__design");
  var content = $(head).html();
  var text = $.trim(content);
  var newHtml = "";
  text.split("").forEach(function(v) {
      newHtml += "<span>" + v + "</span>";
  });
  $(head).html(newHtml);
  var count = $(head).text().length;
  for(i = 1; i <= count; i++){
    $("span:eq(" + i + ")").css({
      "animation-delay": i/4 +"s",
    })
  }
})

HTMLで指定したclass名を呼び出して、jQueryの命令を書いています。
そのためclass名を変更する場合HTML・jQueryそれぞれ変更してください。
基本的なアニメーションの命令はCSSで設定していますが、実行するタイミングのみjQuery側で制御しています。
CSS3のanimationプロパティに対する理解が必要となりますね。

解説

大まかな考え方は以下の通りです。

1.h1要素内のテキストを1文字ずつ分割
2.分割したそれぞれのテキストをspanタグで囲む
3.h1要素の内容を、spanタグで囲まれたテキストに変更する

コードの量は多くないですが、見慣れない記述や複雑に見える記述があるかもしれません。

それでは1行ずつ見ていきましょう。

まず変数headを定義し、class名.head__designを代入します。
これは単純にclass名を呼び出しやすくするためのものです。

var head = $(".head__design");

変数contentを定義し、.head__design内のhtmlを取得して代入します。
これも代入した値を呼び出しやすくするためです。
変数は比較的このように扱うことが多いですね。

var content = $(head).html();

変数textを定義し、content内にある全ての改行・空白・タブを削除します。$.trimの命令を使うことで全ての改行・空白・タブを削除することができます。

var text = $.trim(content);

変数newHTMLを定義します。
これは分割してspanで囲んだテキストを入れるための変数になります。
※初期値を指定しないとh1の冒頭にundefinedの文字列が出力されるため、空の初期値を用意します。

var newHtml = "";

変数text内の文字列を1文字ずつ分割します。
splitという命令文の引数に””を用いることで1文字ずつ分割することができます。
forEach文を用いてspanタグと変数vに代入した各テキストを、1文字ずつnewHtml内に格納していきます。

text.split("").forEach(function(v) {
      newHtml += "<span>" + v + "</span>";
  });

newHtmlに代入したHTMLを変数headに代入します。

$(head).html(newHtml);

ここまででh1タグ内のテキストを1文字ずつ分割し、spanタグで囲むことができました!
ブラウザの検証ツールで見るとこのようになっているはずです。

h1要素内のテキストが1つずつ分割されて、spanで囲まれていますね。

最後に1文字ずつタイミングをずらしてアニメーションさせる記述を見ていきましょう。

var count = $(head).text().length;
  for(i = 1; i <= count; i++){
    $("span:eq(" + i + ")").css({
      "animation-delay": i/4 +"s",
    })
  }

まず変数countを定義し、headのテキストの数を取得して代入します。
lengthによる命令で数を取得することができます。)
続いてfor文を使用して以下の命令をcountの数だけ繰り返します。

・一つ一つのspanに対してanimation-delayプロパティを指定
・値に変数iを4で割った数値を指定
・for文でiの値が処理のたびに1増えていくので、animation-delayが徐々に変化する(アニメーションのタイミングがずれる)

という内容になります。

基本的なアニメーションの記述はCSSに書き、animation-delayに対する指示のみjQueryに記述することでanimation-delayの命令をより簡潔に記述することができます。
CSSでspanを順番毎に指定して、一つずつ命令を書いたら大変ですよね・・・(それでもできるのですが)

以上で完成となります!

RECENT ENTRIES

  • 【Javascript】GSAPで高度なアニメーションをお手軽に実装しよう

    VIEW MORE
  • 【Javascript】GSAPを使ってアニメーション実装をもっと自由に!

    VIEW MORE
  • 【Jsライブラリ】vanilla-tilt.jsで目を引くホバー演出を実装しよう

    VIEW MORE

CONTACT

contact