最初は見えない状態から、ブラウザをスクロールすると
画像のように要素が下から上へ少しだけ動きながらフワッとフェードインする方法をやっていきます。
HTMLコード
<body>
<header>
<h1>タゴ'sクリエイト</h1>
<nav>
<p>Global-Navigation</p>
</nav>
</header>
<main>
<div class="scrollA scrollUp">
<h2>Content</h2>
</div>
<div>
・
・
・
・
</main>
<script src="example.js"></script>
</body>
まずこの様なものを表示させます。
この黄色の「Content」部分に対して、「Content」の下辺が画面の下辺より上にいくと、
元々消しておいた「Content」が下から上にフワッとフェードインするものを作っていきます。
JSコード
window.addEventListener('load',fadeCheck); //1
window.addEventListener('scroll',fadeCheck,{passive:true}); //2
function fadeCheck(){ //3
var cont=document.querySelector('.scrollA'); //4
if(window.innerHeight>cont.getBoundingClientRect().bottom){ //5
cont.classList.add('fadeJS'); //6
}
}
CSSコード
.scrollA{
opacity: 0;
}
.scrollUp{
transform: translate(0,50px);
}
.fadeJS{
opacity: 1;
transform: none;
transition: all 2s ease;
}
今回は「mane」要素の中にある、一番最初の「div」要素にのみフェードインを適用させるコードです。
では上から順に説明です。
JSコード
1、まず「addEventListener」で、ウィンドウをロードした時に「fadeCheck」関数を呼び出します。(この「fadeCheck」は後で説明しますが、大まかに言うと「HTMLの要素にclassを追加するか判定」という意味です)
2、また「addEventListener」を使い、ウィンドウをスクロールした時にも「fadeCheck」関数を呼び出します。
ここで第三引数に「{passive:true}」を入れていることの説明を簡単にします。
「スクロールジャンク」と呼ばれる、主にモバイル端末で起きる、スクロールの際JSの処理待ちのためのカクカクする現象があり、
これは「PreventDefault」という処理を中断して他の処理をさせるメソッドがあるかないかをスクロールのたびにブラウザ側がチェックしているために起こっています。
「addEventListener」の第三引数に「{passive:true}」を入れることで、事前に
このページには「PreventDefault」メソッドがないよ!
と宣言しているということになります。
なので、「{passive:true}」を入れることによって、「スクロールジャンク」を防ぎスムーズにスクロールできるようになるというわけです。
3、次は先ほどの「fadeCheck」関数を記述していきます。
4、まずは「querySelector」でHTMLのコンテンツのクラス名「.scrollA」を要素1つだけ取得、それを変数「cont」に代入します。
5、次にif文を設定、「getBoundingClientRect」により「cont」要素に対し下辺を基準高さとし、「window.innerHeight(ブラウザの表示高さを数値化)」より小さい(画面下部よりさらに上に行き、ブラウザ上に見える状態)の場合という条件式を記述。
ここで「getBoundingClientRect」について説明です。
これは「要素.getBoundingClientRect().X」とすることで、
(今回Xは「bottom」を指定してますが、他の指定種類については後述します)
要素のボックス(border、padding含む)の下辺の座標が、ブラウザの表示部分(ビューポート)の基準点である左上(左上が「0,0」となっている)を基準として、どの位置にいてるかを数値として取得できます。
この「bottom」の他にも「top,left,right」等があり、それぞれボックスの上辺、左辺、右辺を意味します。
例えば「スクロールしてh1要素の上辺が画面上部に設置するとイベントを起こしたい」等の時は、
「top」を使用するといいと言うことですね。
6、条件が当てはまる「cont」要素に「fadeJS」というクラスを付与します。
CSSコード
「scrollA」クラスと「scrollUp」クラスには、まずJSが適用される前の待機状態を記述します。
今回だと「scrollA」の「opacity(不透明度)」を「0」にして見えなくし、
「scrollUp」の「transform」を使用し「translate(要素の位置)」の値を50px下にしています。
そしてJSが適用されて追加されるクラスである「fadeJS」は、
「opacity」を初期値の「100」に戻し、「transform」も初期値の「none」に戻します。
このままではJSが適用されるといきなり「fadeJS」が適用されるため、ただ所定の場所にパッと現れるだけになってしまいます。
なので、「fadeJS」に「transition」を追加し、「all(トランジション対象のCSSプロパティ→全て)」「2s(2秒間かけてアニメーション)」「ease(なめらかに始まりなめらかに終わる)」の3つを記述します。
こうすることで、「scrollA」と「scrollUp」の状態から「fadeJS」の状態に変わる時に、
「transition」の変化を行いながら変わっていってくれるようになります。
これで要素1つに対して、スクロールすると要素がフワッと出現する方法は以上になります。
ですがこのHTMLの表示ページだと大体はコンテンツ全部に対して先ほどまでのアニメーションを適用させたいと思いますので、
ページ内の全てのコンテンツ要素に対してアニメーションをかけていきます。
HTMLコード
<body>
<header>
<h1>タゴ'sクリエイト</h1>
<nav>
<p>Global-Navigation</p>
</nav>
</header>
<main>
<div class="scrollA scrollUp">
<h2>Content</h2>
</div>
<div class="scrollA scrollUp">
<h2>Content</h2>
</div>
<div class="scrollA scrollUp">
・
・
・
・
</main>
<script src="example.js"></script>
</body>
JSコード
window.addEventListener('load',fadeCheck);
window.addEventListener('scroll',fadeCheck,{passive:true});
function fadeCheck(){
var cont=document.querySelectorAll('.scrollA'); //変更点1
for(var i=0;i<cont.length;i++){ //変更点2
if(window.innerHeight>cont[i].getBoundingClientRect().bottom){ //変更点3
cont[i].classList.add('fadeJS'); //変更点4
}
}
}
CSSは先ほどまでのままで、JSを少し書き換え、HTMLのコンテンツ要素全てに同じクラスを付与しました。
またまたJSの上から変更や追加された記述を説明していきます。
変更点1、HTMLの対象要素が複数あるため、Allを使用しクラス名「.scrollA」のついている要素を全て取得、それを変数「cont」に代入します。
この「querySelectorAll」を使用し変数Xに代入すると、変数Xにインデックス番号が付与され、HTMLの上から1番目のクラスが「変数X[0]」となり、2番目が「変数X[1]」というふうになります。
変更点2、「.scrollA」クラスが付与されている要素の数だけ後の処理を繰り返すfor文を作成します。
変更点3、if文を作成し、「getBoundingClientRect」により複数の「cont」要素全てに対し、下辺を基準高さとし、「window.innerHeight(ブラウザの表示高さを数値化)」より小さい(画面下部よりさらに上に行き、ブラウザ上に見える状態)の場合という条件式を、インデックス番号0~6全てに適用します。
変更点4、複数「cont」要素全てに対し、条件が当てはまるごとに「fadeJS」というクラスを付与します。
画像じゃ分かりにくいですが、要素1つに対し適用していたフェードインアニメーションを、「content要素」の全てに適用することができました!