ネットサーフィン中に、カウントダウン機能を盛り込んだスライドショーを見つけたので、実装しました。
↑こんなヤツですね。
slickを使ったスライドショーの実装
スライドショーはjQueryのプラグインである「slick」で実装します。
公式サイトを参考にしつつ、自分のディレクトリ構造などと比較しながら、実装します。
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" type="text/css" href="slick/slick.css"/>
<link rel="stylesheet" type="text/css" href="slick/slick-theme.css"/>
<script type="text/javascript" src="jQuery-3.5.1.min.js"></script>
<script type="text/javascript" src="slick/slick.min.js"></script>
</head>
<body>
<div class="your-class">
<div>your content</div>
<div>your content</div>
<div>your content</div>
</div>
<script>
$(document).ready(function(){
$('.your-class').slick({
});
});
</script>
</body>
</html>
僕の場合、上記のようなコードです。
ディレクトリ構造が気になる方は、GitHubでご確認ください。
コードを書いて、「your content」と1つだけ表示されたら、slickの導入はうまくいっています。
一方で、次のような表示の場合、slickが上手く導入できてないので確認が必要です。
こういった場合の原因としては、
- 参照先を間違えてる
- CSSやjavascriptの記載順を間違えてる(slickは一番最後に書く)
- 単純なコピペのミス
- (CDNの場合)そもそもパソコンとネットが繋がってない
こういったものが考えられます。
いずれにせよ、大半の原因はケアレスミスにあるようです
スライドショーのデザインの整形
さて、話を戻して…
O-DANで拾ってきたそれっぽい画像を使って、スライドショーを実装します。
<div class="slider-outer">
<div class="your-class">
<div class="count-down">
<img src="img/audience.jpg" alt="">
</div>
<img src="img/soccer.jpg" alt="">
<img src="img/bouldering.jpg" alt="">
</div>
</div>
<script>
$(document).ready(function(){
$('.your-class').slick({
autoplay:true,
autoplaySpeed: 3000,
dots:true,
fade: true,
speed: 2000,
});
});
</script>
.count-down >img{
width: 100%;
}
@media screen and (min-width: 960px) {
.slider-outer{
width: 60%;
margin: auto;
}
}
@media screen and (max-width: 959px) {
.slider-outer{
width: 90%;
margin: auto;
}
}
余談ですが、div内に画像を入れる際は、画像自体に幅(width=100%)を指定しないと枠からはみ出るので注意です。
下図のように、写真の下にドットが表示されてたらOKです
カウントダウン機能の作成
次にカウントダウン機能の設定です。
僕は新しい機能を実装する際、まずは新しい機能だけを単独で実装します。
そうしないと、エラーが起きたときに、
- 新規機能のコード
- 新規機能と既存機能との接続
いずれの部分に問題が起きてるのか、判断が出来なくなるからです。
なので、カウントダウン機能をスライドショーと切り離して実装するために、「index.html」を次のように修正します。
<p id="countDownMsg"></p>
<div class="slider-outer">
<div class="your-class">
<div class="count-down">
<img src="img/audience.jpg" alt="">
</div>
<img src="img/soccer.jpg" alt="">
<img src="img/bouldering.jpg" alt="">
</div>
</div>
<script>
// スライドショー本体のコード
$(document).ready(function(){
$('.your-class').slick({
autoplay:true,
autoplaySpeed: 3000,
dots:true,
fade: true,
speed: 2000,
});
});
// カウントダウン部分のコード
$(document).ready(function(){
var openingDay = new Date('2021-07-23T00:00:00.000+09:00');
var openingCeremony = new Date('2021-07-23T20:00:00.000+09:00');
var closingSession = new Date('2021-08-08T20:00:00.000+09:00');
var times = 24 * 60 * 60 * 1000;
setInterval(function(){
var today = new Date();
var diff = openingDay - today;
var countDownDay = Math.ceil(diff / times);// 開幕当日までの残り日数 //
if (today < openingDay) { // 開幕式当日までの間 //
$("#countDownMsg").html("<p>オリンピック開幕まで<br>残り<span id='count-down-day'></span>日!</p>");
$("#count-down-day").html(countDownDay);
} else if(today < openingCeremony) { // 開幕式当日~開幕式前 //
$("#countDownMsg").html("<p>オリンピック<br><span id='count-down-day'></span></p>");
$("#count-down-day").html("本日開会!");
} else if(today < closingSession ) { // 大会期間中 //
$("#countDownMsg").html("<p>オリンピック<br>現在、<span id='count-down-day'></span></p>");
$("#count-down-day").html("開催中!");
} else { // 閉幕後 //
return;
}
},1000);
});
</script>
こんなかんじですね。
jQueryの部分が長いので、動きをザックリ説明すると、
- 「開会式」など特定の日時を設定する(27~29行目)
- 現在の日時を取得する(33行目)
- ①と②の差を活用して、「あと〇日」の表示と作る(34~35行目)
- 現在日時に応じて、表示内容を変更する(37~49行目)
こんなかんじです。
画面としては次のような状態になってるかと思います。
33行目の括弧内に適当な日付を入れて、残り日数の表示が変わればOKです
カウントダウン機能は悩んだ部分が多かったので、少し補足します。
時刻表示について
27~29行目で、「開会式」など特定の時刻を設定してますが、地味に曲者でした。
具体的には、
パソコンでは表示されるのに、スマホだと日時が表示されない!
という事態が生じました。
時刻表示は特定フォーマット以外はブラウザごとに扱いが異なるというjavascriptの特性が原因でした。
本来、全てのブラウザで表示するには、時刻表示を共通フォーマットの「ISO 8601 方式」で設定すべきでした。
なので、日付はISO8601方式に沿った形で記載してます。
else ifは前の条件が当然false
一番最初、40&43行目の「else if」の条件式は、「前の条件がfalse&〇〇」という記載をしてました。
具体的なコードにすると、
if (today < openingDay) {
…
} else if(openingDay <= today && today < openingCeremony) {
…
} else if(openingCeremony <= today && today < closingSession ) {
…
} else {
…
}
こんなかんじです。
「少し冗長的な条件式だなぁ」と思って気付いたんですが、else if構文って、
- 条件式Aを判断する
- (条件式Aがfalseの場合)条件式Bを判断する
- (条件式Bがfalseの場合)条件式Cを判断する
- …
こんな動きをするので、②の段階で「条件式A=false」は確定なんですよね。
なので、完成したコードのように前の条件式と重なる部分は削除しました
完成したコードとデモ画面
最後にスライドショーとカウントダウン表示を合体して完成です。
完成したコードとデモ画面は次のとおり。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" type="text/css" href="slick/slick.css"/>
<link rel="stylesheet" type="text/css" href="slick/slick-theme.css"/>
<script type="text/javascript" src="jQuery-3.5.1.min.js"></script>
<script type="text/javascript" src="slick/slick.min.js"></script>
<title></title>
</head>
<body>
<div class="slider-outer">
<div class="your-class">
<div class="count-down">
<p id="countDownMsg"></p>
<img src="img/audience.jpg" alt="">
</div>
<img src="img/soccer.jpg" alt="">
<img src="img/bouldering.jpg" alt="">
</div>
</div>
<script>
// スライドショー本体のコード
$(document).ready(function(){
$('.your-class').slick({
autoplay:true,
autoplaySpeed: 3000,
dots:true,
fade: true,
speed: 2000,
});
});
// カウントダウン部分のコード
$(document).ready(function(){
var openingDay = new Date('2021-07-23T00:00:00.000+09:00');
var openingCeremony = new Date('2021-07-23T20:00:00.000+09:00');
var closingSession = new Date('2021-08-08T20:00:00.000+09:00');
var times = 24 * 60 * 60 * 1000;
setInterval(function(){
var today = new Date();
var diff = openingDay - today;
var countDownDay = Math.ceil(diff / times);// 開幕当日までの残り日数 //
if (today < openingDay) { // 開幕式当日までの間 //
$("#countDownMsg").html("<p>オリンピック開幕まで<br>残り<span id='count-down-day'></span>日!</p>");
$("#count-down-day").html(countDownDay);
} else if(today < openingCeremony) { // 開幕式当日~開幕式前 //
$("#countDownMsg").html("<p>オリンピック<br><span id='count-down-day'></span></p>");
$("#count-down-day").html("本日開会!");
} else if(today < closingSession ) { // 大会期間中 //
$("#countDownMsg").html("<p>オリンピック<br>現在、<span id='count-down-day'></span></p>");
$("#count-down-day").html("開催中!");
} else { // 閉幕後 //
return;
}
},1000);
});
</script>
</body>
</html>
.count-down{
position: relative;
}
.count-down >p{
display: block;
position: absolute;
text-shadow: 2px 2px 4px black;
color: white;
font-weight:bold;
left: 10%;
}
.count-down >img{
width: 100%;
}
@media screen and (min-width: 960px) {
.slider-outer{
width: 60%;
margin: auto;
}
#count-down-day{
color: tomato;
font-size: 70px;
}
.count-down >p{
font-size: 40px;
}
}
@media screen and (max-width: 959px) {
.slider-outer{
width: 90%;
margin: auto;
}
.count-down >p{
font-size: 25px;
}
#count-down-day{
color: tomato;
font-size: 45px;
}
}
デモ画面はこちら。
まとめ
今回一番ハマったのは、「カウントダウンがsafariで表示されない」という部分です。
やっぱりsafariは少し曲者ですね。笑
とはいえ、おかげで一つ成長できたわけだし、teratailデビューも果たしたので良しとします。
さて、最後に余談ですが、僕は一つだけ自慢できることがあります。
それは、
- 30代
- 妻子持ち
- ブラック企業
というハードモードの中、スクールには通わず、半年の独学で上場企業から内定したことです。
そのときは、
- ドットインストール
- 関連書籍
- Ruby on Rails チュートリアル
など、いわゆる「王道」の教材も使いましたが、一番参考になったのはUdemyで買った動画教材。
特にCSSやJavaScriptの学習で参考になった教材がコチラです。
プログラミングを勉強してる方なら「Udemy」って名前は聞いたことがあるかと思いますが、
- 大手企業「ベネッセ」が事業パートナーを務めてるので安心
- 専門書よりも安く買えるので、お試し購入がしやすい
- スマホから動画で学べるので、通勤中や昼休みにも勉強できる
など、独学者にはかなりオススメのコンテンツです。
次の記事で詳しく解説してるので、スキルアップをしたい独学者の方はぜひ読んでみてください
それでは!