jQueryかJSでテキストを1文字ずつspanで囲う方法(空白・改行削除対応)
見出しなどにJSでデザインを加えるときに、1文字ずつアニメーションを加えたいことがありますよね。HTMLで1文字ずつにspanを書き足すのは非現実的なので、jQueryで対象のテキストに一括でspanを追加してしまいましょう。
やりたいこと
<!-- 元のHTML -->
<h1 id="js-page-title">
About us
</h1>
<!-- 1文字ずつspanを加えたHTMLにしたい -->
<h1 id="js-page-title">
<span>A</span><span>b</span><span>o</span><span>u</span><span>t</span> <span>u</span><span>s</span>
</h1>
<!--
わかりやすいように改行すると以下のようなイメージです。
実際には半角スペースが含まれてしまうため改行しない。
-->
<h1 id="js-page-title">
<span>A</span>
<span>b</span>
<span>o</span>
<span>u</span>
<span>t</span>
<span>u</span>
<span>s</span>
</h1>
結論
/**
* jQuery版
**/
// コンテナを指定する
var container = $("#js-page-title");
// コンテナのコンテンツを取得
var content = $(container).html();
// コンテンツから空白や改行を削除
var text = $.trim(content);
// 新しく挿入するHTMLの変数を定義
var newHtml = "";
// text を1文字ずつ分割して span を追加する
text.split("").forEach(function(v) {
newHtml += "<span>" + v + "</span>";
});
// コンテナに作ったHTMLを挿入しする
$(container).html(html);
/**
* JS版
**/
// コンテナを指定する
var container = document.querySelector('#js-page-title'); // JS版
// コンテナのコンテンツを取得
var content = container.textContent;
// コンテンツから空白や改行を削除
var text = content.trim(); // JS版
// 新しく挿入するHTMLの変数を定義
var newHtml = "";
// text を1文字ずつ分割して span を追加する
text.split("").forEach(function(v) {
newHtml += "<span>" + v + "</span>";
});
// コンテナに作ったHTMLを挿入しする
container.innerHTML = newHtml;
少し細かく書いていますが、まとめて書いちゃっても大丈夫です。
これで1文字ずつspanで囲われたと思うので、その他のJSやCSSアニメーションと連携すればOK。
プラグイン化する場合
当社の場合はプラグイン化して、使いまわせるようにしています。
// プラグイン化
$.fn.letterSpan = function() {
// idではなくclassを使い複数設定する想定で each を使う
$(this).each(function() {
var text = $.trim(this.textContent),
html = "";
text.split("").forEach(function(v) {
html += "<span>" + v + "</span>";
});
this.innerHTML = html;
});
};
// 上記同様に #js-page-title に反映
$("#js-page-title").letterSpan();
// .js-letter-span クラスのコンテナ全てに反映
$(".js-letter-span").letterSpan();
こんな感じでプラグイン化すると使いやすくなります。
ちなみに、textをforEachで回す時に、クラスを追加したりdata-offsetやdata-delayなんていう感じで追加してあげるとさらに便利になったりもします。