マウスホイールで切り替わる全画面コンテンツをつくってみた
- 2019.03.22
- javascript+css つくったもの
- 脱jQuery
マウスホイールで切り替わる全画面表示のコンテンツをつくってみました。
マウスホイールに反応して、次のページがフェードインしてくるようにしています。
スマホの場合は上下のフリックで切り替わるようにしました。
まずはデモをご確認ください。
コードと解説
html
<div class="contents page1 show">1</div> <div class="contents page2">2</div> <div class="contents page3">3</div> <div class="contents page4">4</div> <div class="contents page5">5</div> <div class="contents page6">6</div> <div class="contents page7">7</div> <div class="contents page8">8</div> <div class="contents page9">9</div> <div class="contents page10">10</div>
10個のコンテンツを用意しました。
.show というクラスを付け外しすることで、コンテンツを切り替えます。
一番最初のコンテンツはあらかじめ .show を付けておき、表示させておきます。
css
body {
position: relative;
width: 100%;
height: 100vh;
margin: 0;
padding: 0;
}
.contents {
width: 100%;
height: 100vh;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 0;
transition: 1s;
text-align: center;
line-height: 100vh;
}
.page1 { background-color: aquamarine;}
.page2 { background-color: lightsalmon;}
.page3 { background-color: wheat;}
.page4 { background-color: cornflowerblue;}
.page5 { background-color: gold;}
.page6 { background-color: olive;}
.page7 { background-color: khaki;}
.page8 { background-color: orange;}
.page9 { background-color: gainsboro;}
.page10 { background-color: yellow;}
.show {
opacity: 1;
}
body にposition: relative; を入れておきます。
.contents に各コンテンツのスタイルを指定。
幅・高さを画面いっぱいに。
position: absolute; で画面固定。
opacity: 0; にしておき、あらかじめ非表示とします。
transition: 1s; を入れ、フェードインのアニメーションするように。
.show に opacity: 1; を入れ、この .show を付け外しすることでコンテンツを入れ替えます。
javascript
var contents = document.querySelectorAll('.contents'); // コンテンツの取得
var count = 1; // 表示させるコンテンツの番号を設定
// スマホの場合、タッチスライドで動かす
if ((navigator.userAgent.indexOf('iPhone') > 0 && navigator.userAgent.indexOf('iPad') === -1) || navigator.userAgent.indexOf('iPod') > 0 || navigator.userAgent.indexOf('Android') > 0) {
// タッチの位置を取得するための変数
var touchStart,
touchMove,
touchDistance;
// タッチし始めた位置
window.addEventListener('touchstart', function (e) {
touchStart = event.touches[0].pageY;
touchMove = event.touches[0].pageY;
});
// タッチし、動かした位置
window.addEventListener('touchmove', function (e) {
touchMove = event.touches[0].pageY;
});
// タッチ終了時に
window.addEventListener('touchend', function (e) {
// タッチの開始位置から、移動後の位置を引く
touchDistance = touchStart - touchMove;
// タッチスライドが上方向だったら
if (touchDistance > 70) {
// countの値をプラス
count++;
// countの値の上限をコンテンツの数にする
if (count >= contents.length) {
count = contents.length;
}
}
// タッチスライドが下方向だったら
else if (touchDistance < -70) {
// countの値をマイナス
count--;
// countの値の下限を1とする
if (count <= 1) {
count = 1;
}
}
// タッチスライドがなかったら、何もしない
else {
}
// 一旦コンテンツを全部非表示にして
for (var i = 0; i < contents.length; i++) {
contents[i].classList.remove('show'); // showクラスを削除して非表示に
}
// 該当のコンテンツのみ表示
contents[count - 1].classList.add('show'); // showクラスを付与して表示
});
}
// PCの場合、ホイールで動かす
else {
var countFlg = false; // ホイールのイベントをやたらめったに取得しないためのフラグ
// ホイールの動きがあったら
window.addEventListener('wheel', function (e) {
// countFlgがfalseの場合だけ動く
if (!countFlg) {
// ホイールが下方向だったら
if (e.deltaY > 0) {
// countの値をプラス
count++;
// countの値の上限をコンテンツの数とする
if (count >= contents.length) {
count = contents.length;
}
}
// ホイールが上方向だったら
else if (e.deltaY < 0) {
//countの値をマイナスにする
count--;
// countの値の下限を1とする
if (count <= 1) {
count = 1;
}
}
// countFlgをtrueにする
countFlg = true;
// 数秒後、countFlgをfalseにして、またホイールのイベントで動くように
setTimeout(function () {
countFlg = false;
},1000 ); // 秒数を指定。ミリ秒
// 一旦コンテンツを全部非表示にし、
for (var i = 0; i < contents.length; i++) {
contents[i].classList.remove('show'); // showクラスを削除して非表示に
}
// 該当コンテンツのみ表示
contents[count - 1].classList.add('show'); // showクラスを付与して表示
}
});
}
スマホの場合は上下のフリックで、PCの場合はマウスホイールで反応させます。
スマホはフリックで
まずはスマホの場合。
touchstart でタッチを開始した位置を記録。
touchmove でタッチして移動した位置を記録。
touchend でタッチが離れたときに、touchstart(タッチの開始位置)からtouchmove(タッチして移動した位置)を引き算。移動距離を測ります。
上方向に動いたらcountの数値をプラス、下方向に動いたらマイナス。
一旦全コンテンツから .show を削除し非表示。
コンテンツの count番目に .show を付与して表示させます。
このときtransition: 1s; が効いているので、フェードインのアニメーションになります。
スマホの場合のポイント
touchstart でタッチを開始した時点で、
touchstart(タッチを開始した位置)と一緒に、touchmove(タッチして移動した位置)にもタッチを開始した位置を代入しておきます。
これをしておかないと、二回目のタッチの時に、ひとつ前の touchmove の値が残ってしまい、正しく動いてくれません。
PC時のホイールでの制御
wheelイベントで、マウスホイールの動きを取得。
event.deltaYの移動距離が上方向か下方向かで、countの値とプラスもしくはマイナス。
一旦全コンテンツから .show を削除し非表示に。
count番目のコンテンツに .show を付与して表示させます。
PCホイール取得時のポイント
何も気にせずやってしまうと、マウスホイールをぐりぐりっとたくさん動かしたときに、countの値をたくさん変化してしまいます。
なので一回目のホイールの動きだけを検知しするようにします。
countFlg という変数を用意。これが false の時だけホイールが反応するようにします。
反応したら countFlg を true にします。
setTimeout を使用し、trueになってから1秒後に countFlg を false に戻しています。
バリエーション
cssを変更するだけで、いろんな表示の仕方が可能です。
たとえば、フェードインしながら下からせり上がってくるようなバージョンを作ってみました。
以下、デモです。
css
cssだけ変更をしています。
body {
position: relative;
width: 100%;
height: 100vh;
margin: 0;
padding: 0;
overflow: hidden;
}
.contents {
width: 100%;
height: 100vh;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, 100%);
opacity: 0;
transition: 1s;
text-align: center;
line-height: 100vh;
}
.page1 { background-color: aquamarine;}
.page2 { background-color: lightsalmon;}
.page3 { background-color: wheat;}
.page4 { background-color: cornflowerblue;}
.page5 { background-color: gold;}
.page6 { background-color: olive;}
.page7 { background-color: khaki;}
.page8 { background-color: orange;}
.page9 { background-color: gainsboro;}
.page10 { background-color: yellow;}
.show {
transform: translate(-50%, -50%);
opacity: 1;
}
.contents に transform: translate(-50%, 100%); を追加。
あらかじめ画面の下の外に配置しておきます。
.show に transform: translate(-50%, -50%); を追加。
.show が付与されて表示されるときに、位置を画面内に持ってきます。
-
前の記事
振ると色が変わるスマホ用コンテンツをつくってみた 2019.03.21
-
次の記事
スクロールで要素が画面の中に入ったらふわっとフェードインするコンテンツ 2019.03.23