初めまして。講師の藤井郁です。
簡単な機能だったらプラグインに頼らず自分でコードを書きたいと思い、挑戦することがあります。
イメージ通りにはいかず、想定以上の時間を費やすこともありますが、ひらめいたことが上手くと嬉しいですし、完成したときの達成感は大きいです。
このような満足感や高揚感をみなさんと共有できたらいいなと思い、ブログを始めました。
最新の投稿ブロックとJavaScriptを組み合わせて、投稿のスライドショーを作成する方法を紹介します。
実践編のチャレンジ課題①で使える機能です。自分で解決したいという方は、ネタバレ注意です!
なお、この記事はJavaScriptの知識がある方を対象としています。
1. HTML要素の取得
まずは、最新の投稿を表示するHTML要素を取得しましょう。
要素を取得するための関数はいろいろありますが、私は、「querySelector」または「querySelectorAll」という関数を使います。
これらの関数は、CSSと同じセレクターを使用して要素を取得するので、最新の投稿ブロックに「ticker」というクラスを追加します。
開発者ツールで確認すると、次のようなHTMLが追加されていることが分かります。
<ul class="ticker">
<li><a href="[投稿のURL1]">タイトル1</a></li>
<li><a href="[投稿のURL2]">タイトル2</a></li>
<li><a href="[投稿のURL3]">タイトル3</a></li>
<li><a href="[投稿のURL4]">タイトル4</a></li>
<li><a href="[投稿のURL5]">タイトル5</a></li>
</ul>
5つのリスト項目を取得したいので、「querySelectorAll」関数を使います。
const posts = document.querySelectorAll('.ticker li');
値を変更する必要がないので、「posts」という定数に代入します。
開発者ツールのコンソールを利用して確認してみましょう。
コードを直接入力することができます!
2. スライドショーの作成
つぎに、この「NodeList」を使ってスライドショーを作成しましょう。
使用している関数などについては、MDNのNodeListや関数を参照してください。
NodeList APIのforEach()メソッドのブラウザーサポートを確認することも重要です。
コードの書き方はさまざまなので、一例として参考にしてください。
let index = 0; // postsのインデックスとして使用する
function ticker() {
// 最新の投稿のHTML要素を取得する
const posts = document.querySelectorAll('.ticker li');
// 全てのリスト項目のdisplayプロパティ値をnoneに変更する
// 無名アロー関数を使用しています
posts.forEach( post => {
post.style.display = 'none';
});
// indexの値に基づき1件の投稿を表示する
posts[index].style.display = "block";
// indexの値をインクリメントする
// indexの値が5以上になったら0に戻す
index++;
if (index >= posts.length) {index = 0 }
// 5秒ごとに表示する投稿を変更する
setTimeout(ticker, 5000);
}
3. 気を付けること
最新の投稿がレンダリングされる前にJavaScriptコードを実行すると、どうなるな分かりますか?
答えは明白ですね。取得したいHTML要素が見つかりません。
この問題を回避する方法はさまざまですが、ここでは、「addEventListener」関数を使用して、ページがロードされた後にのみコードが実行されるようにする方法を紹介します。
document.addEventListener('DOMContentLoaded', function() {
ticker();
});
おまけ
アニメーションを付けてみましょう。
上記のJavaScriptとは異なるコードを紹介します。いろいろ試してみることで、より最適なコードを見つけられます。
document.addEventListener('DOMContentLoaded', () => {
ticker();
});
let index = 0;
const ticker = () => {
const posts = document.querySelectorAll('.ticker li');
// 全ての投稿を非表示にする
posts.forEach(post => post.style.display = 'none');
// indexの値に基づき1件の投稿を表示する
posts[index].style.display = 'block';
// 次の投稿にインデックスを進める
index = (index + 1) % posts.length;
setTimeout(ticker, 5000); // 5秒ごとに投稿を変更
};
最新の投稿ブロックに「roll」というクラスも追加して、垂直方向にフェードインするアニメーションを適用します。
.roll li a {
position: relative; /* 位置の基準を相対的に設定 */
animation: animatebottom 1s ease-in-out; /* アニメーションの効果を追加 */
}
@keyframes animatebottom {
from {
bottom: -1rem; /* 要素を下に1rem移動 */
opacity: 0; /* 透明度を0に設定 */
}
to {
bottom: 0; /* 要素を元の位置に戻す */
opacity: 1; /* 透明度を1に設定 */
}
}
animation プロパティは複合プロパティで、複数の値を一度に設定できます。
- animatebottom:アニメーションの名前(animation-name)。@keyframesルールで定義されたアニメーションを指定する。
- 1s:アニメーションの継続時間(animation-duration)。ここでは1秒間に設定している。
- ease-in-out:タイミング関数(animation-timing-function)。アニメーションの進行速度を調整する。ease-in-outは、アニメーションの開始と終了を滑らかにする効果がある。
@keyframes animatebottom は、アニメーションの各ステップを定義します。
実装の仕方をイメージしやすいように編集画面を共有します。
まとめ
JavaScriptとCSSを適用した最新の投稿ブロックのスライドショーはこちらです。5つの投稿を1件ずつ表示しています。