フェードイン/フェードアウトで「ふわっ」とページを切り替える【追記あり】

ネットで見つけたプログラムの TIPS などはなるべく実践を心がけてるんですが、やはりブログ等に残しておかないとすぐに忘れてしまうなぁ と感じてる今日この頃です。そんな訳でなるべく細いネタでもちょくちょく投稿してこうかと思います。
で、今回はページからページへ遷移する際、フェードイン/フェードアウトを使って「ふわっ」とページを切り替える方法について考えてみました。

ふわっとページを切り替える

サンプルを作ってみました。

fade-page

画像をクリックするとフェード付きで画面が切り替わります。1枚の HTML で QueryString を変更してるだけなんで、画面遷移したように見えないかもしれませんが URL は変わってます。

実装方法は以下の通りです。

  1. ページ読み込み時、画面の要素が表示される前に画面全体を非表示にする
  2. ページ読み込みが完了したら、画面全体をフェードインし表示する
  3. 他のページに遷移しようとしたら、画面全体をフェードアウトし非表示にする

ページ読み込み時、画面の要素が表示される前に画面全体を非表示にする

フェードでふわって表示させたいんで、まず画面全体を即座に非表示にする必要があるのですが、CSS で body を display:none とかすんのって反則かなーっと、なんとなく SEO 的にどーなのかと・・・
なのでこれでもちょっと反則っぽいですけど、body タグ直後に以下を記述

  1. <body>
  2. <script>document.body.style.display = 'none';</script>

ちらっとでも画面が見えちゃ変なので苦肉の策ですが・・・他にいい方法あったら誰か教えてください・・・

ページ読み込みが完了したら、画面全体をフェードインし表示する

これは単純にページ読み込み完了後に body をフェードインで表示します。

  1. jQuery(function($){
  2. $('body').fadeIn(1000);
  3. ・・・

素直に jQuery を使用します。

他のページに遷移しようとしたら、画面全体をフェードアウトし非表示にする

「他のページに遷移しようとしたら」というのが肝なわけですが、これは beforeunload イベントで判断つくようです。 以下のようにします。

  1. $(window).on("beforeunload",function(e){
  2. $('body').fadeOut();
  3. });

まとめるとこんな感じです。

  1. <head>
  2. <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
  3. <script>
  4. jQuery(function($){
  5. $('body').fadeIn(1000);
  6. $(window).on("beforeunload",function(e){
  7. $('body').fadeOut();
  8. });
  9. });
  10. </script>
  11. </head>
  12. <body>
  13. <script>document.body.style.display = 'none';</script>
  14. ・・・
  15. </body>

どんなもんでしょう?
各ページで実行しなければいけないんで、1 つの js ファイルにまとめて body タグ直後に読み込むようにしてもいいかもしれません。

ここまで書いて思ったんですが、ひょっとして CSS3 とか使えばもっと簡単にできたりするんでしょうか?誰か知ってたら教えてください 笑
そう言えば書いてて思い出しましたが、昔 IE の独自仕様でこーゆー表示を実現できるタグがありましたね。IE5 とかの時代に試した記憶があります。

【追記】オーバーレイを使って「ふわっ」と感を出す方法

札幌で CSS 関連のセミナー等を開催しご活躍のハムさんから body 要素直下で display = ‘none’ する替わりに div レイヤーを1枚用意してフェードをかけてみては、というアイディアを頂きました。

comment

なるほど!たしかに script タグ書いて body を非表示にするよりスマートですし、他の処理に悪い影響を及ぼす可能性が低いかと思います!

ただこの方法でも毎回 div タグを body 直下に書かなくてはなりません。そこで :before 擬似クラスと content 属性を使用すれば div の記述も省けるのでは?と思い以下のようにしてみました。

:before 擬似クラスで body 要素直下に画面を覆うレイヤーを作成します。fade-layer-off クラスはこのレイヤーをクリアするために使用します。

  1. .fade-layer,
  2. body:before{
  3. content: '';
  4. position:fixed;
  5. top:0;
  6. left:0;
  7. width:100%;
  8. height:100%;
  9. background:#fff;
  10. z-index:99999;
  11. }
  12. body.fade-layer-off:before{
  13. content: none;
  14. }

スクリプトが実行可能な状態になったらまず :before 擬似クラスで定義されたレイヤーをクリアし、直後に同レイヤーと同じ属性構成の div を挿入しフェードアウトさせます。

  1. $('body').addClass('fade-layer-off');
  2. $('<div class="fade-layer"/>').prependTo('body').fadeOut(1000, function(){
  3. $(this).remove();
  4. });
  5. $(window).on("beforeunload",function(e){
  6. $('body').fadeOut();
  7. });

こちらの手法のほうが body 直下に余計な script や div 要素の定義を必要とせず、外部ファイル化すれば css/js ファイルを読み込めだけで良いので汎用的に使用できスマートかと思います。