「toggleやinnerHTMLを使ったコードをよく見かけるけど何をしているか分からない」
「JavaScriptが詳しくないので、アニメーションは記事のコピペで作っている」
「innerHTMLとtextContentの違いが分からない」
本日はそんな方に向けて、JavaScriptで作るアニメーションの基本操作を紹介していきます。
一言で言うと「要素の書き換え」という作業になるのですが、色んな種類のメソッドがあるので初学者の方には理解しずらいのではないかと思います。
1回知ってしまうとググって出来てきた記事をスラスラ読むことができますよ。
また動画もあるので必要に応じて使ってください。
テキストの書き換えはtextContent
アニメーションの基本である「文字の書き換え」を紹介していきます。
特定のイベントに応じて表示する文字の内容を変更することは大変多いです。
まずHTMLを以下のように想定します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<div class="container">
<p class="text">テスト</p>
</div>
</body>
</html>
「テスト」という文字が表示されていますね、こちらの文字を別の文字に変更してみます。
const text = document.querySelector(".text");
text.textContent = "おはよう";
「テスト」から「おはよう」に変更できました。
文字の変更をするには「変更する対象を取得」が事前に必要になり、querySelectorというメソッドでセレクタ名を指定すれば簡単に取得できます。
querySelectorの詳しい解説は別の記事で解説しているので、必要な方は以下よりご覧ください。
「変更する対象」が取得できたら、textContentというメソッドを使うことでテキストの変更が出来ます。
コードも少なく簡単ですね、これだけ知っておくだけでも相当便利かと思います。
textContentとinnerHTMLの違い
ちなみにググっていると以下のような書き方も見かけると思います。
const text = document.querySelector(".text");
text.innerHTML = "おはよう";
「おはよう」という文字に変更できていますね。
結果としては同じことが実現できているのですが、textContentとinnerHTMLは違う使い方になります。
innerHTMLを使うと以下のような書き方も出来るからです。
const text = document.querySelector(".text");
// ここを修正
text.innerHTML = "<span>おはよう</span>";
「おはよう」が引き続き表示されていますね。
表示結果だけでなくブラウザの検証ツールも確認してみましょう。
「おはよう」という文字だけでなく、spanタグも一緒に追加されていますね。
innerHTMLを使うとタグと一緒にテキストを変更することができます。
ちなみにtextContentで同じことをやってみましょう。
const text = document.querySelector(".text");
// ここを修正
text.textContent = "<span>おはよう</span>";
画面上には表示されていますが、タグもそのまま表示されていますね。
これがtextContentとinnerHTMLの大きな違いになりますので覚えておくと良いでしょう。
あとは状況に応じてどちらが適しているかを見極めて使い分けるだけです。
class名の追加、削除はclassList
続いてアニメーションの作成で多く遭遇する「class名の追加、削除」のやり方です。
先ほどのHTMLを引き続き使っていきます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<div class="container">
<p class="text">テスト</p>
</div>
</body>
</html>
<div class=”container”></div>についてclass名を追加してみます。
const container = document.querySelector(".container");
container.classList.add("test");
class名の確認にはブラウザの検証ツールを使っていきます。
もともとcontainerだけでしたが、testという名前も追加されていますね。
classListを使うとclassに関する操作が可能で、classList.add(追加したいclass名)とすることで「class名の追加」が実現できます。
反対にclassList.removeとするとclass名の削除ができます。
const container = document.querySelector(".container");
// ここを修正
container.classList.remove("test");
先ほど追加したtestが削除されて、もとのcontainerのみがclassに記載されていますね。
アニメーションでは装飾の変化や動きをCSSで事前に設定しておき、class名の変化でコントロールする方法がよく使われます。
そのためclass名の追加、削除はアニメーションを作るのに必須の知識と言えます。
ちなみに「class名の追加、削除」をさらにシンプルに書くことができます。
const container = document.querySelector(".container");
// ここを修正
container.classList.toggle("test");
再びtestが追加されていますね。
classListには色んなメソッドが用意されていて、toggleとすると指定したclass名を追加、削除を両方行ってくれます。
公式ドキュメントを見てみましょう。
https://developer.mozilla.org/ja/docs/Web/API/DOMTokenList/toggle
簡単に説明すると、
「引数に指定したclass名が無ければ追加する」
「引数に指定したclass名があれば削除する」
という内容です。
とても便利ですね、先ほどのコードでは一度testは削除してあったので今度は追加してくれたわけです。
実務ではtoggleを使ったclass名の操作が多く、以下のような例が代表的です。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<button class="btn">ボタン</button>
</body>
</html>
const container = document.querySelector(".container");
const btn = document.querySelector(".btn");
btn.addEventListener("click",() => {
btn.classList.toggle("active");
console.log(btn);
});
ボタンを用意しておき、ボタンがクリックするたびにボタンにactiveという名前のclass名を「追加⇔削除」を繰り返すようにしています。
変化を分かりやすくするためにコンソールにログが出力されるようにしてみました。
classList.toggleを使うと、classList.addとclassList.removeを一度に兼ね備えることができることが分かりました。
classやidの値を取得する方法
今度はすでに設定されているclassの値を取得する方法を紹介していきます。
HTMLを以下のように想定します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<div class="container">
<p class="text">テスト</p>
</div>
</body>
</html>
上記のコードでdivタグに設定されているclass名を取得するにはこのように書きます。
取得した結果はコンソールに出力するようにします。
const container = document.querySelector(".container");
const attr = container.getAttribute("class");
console.log(attr); // containerと出力される
getAttributeを使うと引数に指定した属性の値を取得することができて、今回は「class」を引数に入れたので「container」と出力されました。
idの値を取得する場合も同じ方法で実現できます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<div id="container">
<p class="text">テスト</p>
</div>
</body>
</html>
const container = document.querySelector("#container");
const attr = container.getAttribute("id");
console.log(attr); // containerと出力される
classやidを追加する方法
さらに新しくclassやidを追加することもできます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<div class="container">
<p class="text">テスト</p>
</div>
</body>
</html>
const container = document.querySelector(".container");
container.setAttribute("id","container");
setAttributeを使うと新規で属性を追加することができます。
引数は2つ必要で、第一引数に「属性の種類」を指定し第二引数に「属性の値」を指定します。
上記のコードでは「id=”container”」を追加することになっていますね。
classについても同様の使い方ができます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<div id="container">
<p class="text">テスト</p>
</div>
</body>
</html>
const container = document.querySelector("#container");
container.setAttribute("class","container");
ちなみにですが、すでに紹介している「classList.add」でもclassの追加が出来たことを覚えていますでしょうか?
idと違ってclassは一つの要素に複数名をつけることができますので、setAttributeを使った以下のようなケースだと置き換えになってしまいます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<div class="container">
<p class="text">テスト</p>
</div>
</body>
</html>
const container = document.querySelector(".container");
container.setAttribute("class","test");
最初から存在していたcontainerの上書きのような形でtestというclass名が追加されていますね。
「置き換えではなく複数のclass名を共存させたい」という場合には、すでに紹介している「classList.add」の方を使うようにしましょう。