プラグインを使わずにスマホに対応したパララックスを実現する方法

2017/07/17
  • JavaScript
プラグインを使わずにスマホに対応したパララックスを実現する方法

PCでパララックスを実装する場合は、background-attachmentを使用することで簡単に実現することができます。
ですが、スマホではbackground-attachmentが効かないので、簡単に実現することができません。
そこで、今回はスマホでもパララックスを実現するための方法をまとめておきたいと思います。

sample

実現方法

HTML

.section1~4のclassが付いている要素がありますが、今回はsection1、section3は背景画像がない状態。section2、section4に背景が付くような想定で作成しています。

  <div class="wrapper">
   <div class="section1 section">
    <h2>section1</h2>
   </div>

   <div class="section2 section">
     <h2>section2</h2>
   </div>

   <div class="section3 section">
     <h2>section3</h2>
   </div>

   <div class="section4 section">
    <h2>section4</h2>
   </div>
  </div>

css

スマホでパララックスを実現するために、画像を「position: fixed」で裏側に固定させておきます。そして、javaScriptでスクロール位置で画像を切り替えるようにします。

  .section {
   height: 100vh;
   padding: 10% 0;
   text-align: center;
  }

  .section1 , .section3 {
    background: #fff;
  }

  @media screen and (min-width: 737px) {
    /* PCの場合の背景画像 */
    .section2 {
     background: url("img/sample.jpg") no-repeat fixed center center /cover;
    }
    .section4 {
     background: url("img/sample2.jpg") no-repeat fixed center center /cover;
    }
  }
  @media screen and (max-width: 736px) {
    /* スマホの場合の背景画像 */
    .section2:before{
     background-position: center center;
     background-repeat: no-repeat;
     background-size: cover;
     position: fixed;
     top: 0;
     left: 0;
     width: 100%;
     height: 100%;
     content: "";
     z-index: -1;
    }
    /* スマホの場合は同じ要素の背景画像を変更する */
    .section2.bgA:before{
     background-image: url("img/sample.jpg");
    }

    .section2.bgB:before{
     background-image: url("img/sample2.jpg");
    }
  }

JQuery(JavaScript)

javaScriptでは、「$changePoint」を基準に別画像(classを付け替えることで実現)に切り替えます。
今回は「beforeBg」という変数で行っていますが、前の状態を保持して判定に利用しないとスクロールするたびに画像が変わってしまい、ちらつきの原因にもなるので注意してください。

      var beforeBg = '';
      $(window).on('load scroll touchmove', function() {
          $scrollTop = $(window).scrollTop();
          // 画像を切り替える位置
          $changePoint = $('.section3').offset().top;
          if($scrollTop < $changePoint){
            // 同じ背景画像への切替を行わないように判定
            if(beforeBg !== 'bgA'){
              // 新しい画像へ切替
              $('.section2').removeClass('bgB');
              $('.section2').addClass('bgA');
              beforeBg = 'bgA';
            }
          } else {
            if(beforeBg !== 'bgB'){
              $('.section2').removeClass('bgA');
              $('.section2').addClass('bgB');
              beforeBg = 'bgB';
            }
          }
      });