

ページをスクロールした時に、スクロールした距離に応じて、オブジェクトの移動や透過をさせたい。パララックス効果についても簡潔な例を知りたい。


CC BY-SA 3.0
2014-12-11T05:46:01.980
1507
2019-12-26T06:09:31.543
2014-12-11T06:48:43.137
982
905
question
javascript css html5 jquery
jQuery / JavaScriptで、ページスクロール時にアクションを起こしたい


例えば、以下のようなHTMLだと想定する。

[code]

    <body>
        <div id="container">something</div>
    </body>
    
[/code]

例えば、ページ上端からスクロールするにつれ、だんだんと消えていくスクリプト。

[code]

    var $window = $(window); //$windowで$(window)を呼び出せるように変数へ格納。
    $window.scroll(function() {
        $scrollValue = $window.scrollTop(); //ページ上端(正確にはwindowの上端)から現在値がどの位置にいるかを計算。$scrollValueに格納。
        $('#container').css('opacity',1-$scrollValue/$window.height()); //現在位置をwindowの高さで割り、1から引いていくことで、現在のwindowサイズの高さでopacityが0になる。
    }
    
[/code]

上記例の$window.height()部分を任意の数値にすれば、任意の場所で透明化される。また、任意の関数で動的に処理することも可能。また、足し算引き算を応用することで、任意の場所から任意の場所までで変化するという処理も可能。


CC BY-SA 3.0
2014-12-11T05:46:01.980
1508
2014-12-11T05:46:01.980
905
1507
answer


逆に透過状態から表示状態にするなら、CSSで

[code]

    #container{opacity:0;}
    
[/code]

を設定し、透過しておく。その上で、

[code]

    var $window = $(window);
    $window.scroll(function() {
        $scrollValue = $window.scrollTop();
        $('#container').css('opacity',$scrollValue/$window.height());
    }
    
[/code]

とすれば、ページ上端からスクロールするごとにだんだんと表示されるようになる。


CC BY-SA 3.0
2014-12-11T05:47:09.177
1509
2014-12-11T05:47:09.177
905
1507
answer


パララックス効果と一言に言ってもいろいろな表現があるとは思いますが、  
スクロール量に応じてスライドしてきたり文字がフェードしてきたりするようなもののサンプルを書いてみました。

細かいところは気にしていませんので、何かのヒントになればという程度のものです。  
Chromeでしか確認していません。  
（一応 safariでも見てみましたがバウンスのせいか見づらいです）

[code]

    $(window).load(function() {
      var height = $(window).height();
      $(".scr").each(function(i, ele) {
        // ページの高さを確定する。
        var $ele = $(ele);
        var page = $ele.attr("data-page-slidein");
        $ele.css("top", height * page);
        $ele.height(height);
      });
    
      $(window).scroll(function() {
        var scrTop = $(this).scrollTop();
        $(window).scrollLeft(0);
    
        $(".scr").each(function(i, ele) {
          var $ele = $(ele);
    
          var opaPage = $ele.attr("data-page-appear");
          var page = $ele.attr("data-page-slidein");
    
          if (page * height < scrTop) {
            // 画面内にとどまる処理
            $ele.css("top", scrTop);
          }
    
          if (opaPage != "") {
            // 透明度の処理。自分の出現ページが画面に
            // どの程度表示されているかの割合から求めている。
            var value = (opaPage * height - scrTop) / height;
            $ele.css("opacity", 1 - value);
          }
        });
      });
    });
[/code]

[code]

    body {
      margin: 0;
      padding: 0;
    }
    
    .scr {
      height: 100%;
      position: absolute;
      width: 100%;
      top: 100%;
    }
    
    .page1 {
      background-color: #00b3ee;
    }
    
    .page2 {
      background-color: #d58512;
    }
    
    .first-page,
    .last-page {
      background-color: white;
    }
[/code]

[code]

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <!-- data-page-slidein  何ページ分スクロールすると そのdivがスライドしてくるか -->
    <!-- data-page-appear   divのFadeInが完了するタイミング ： 何ページ分スクロールしたとき不透明になる。ブランクならフェードしない -->
    <div class="scr first-page" data-page-slidein="0" data-page-appear="">
      Index Page
    </div>
    
    <div class="scr page1" data-page-slidein="1" data-page-appear="">
      ページ１
    </div>
    
    <div class="scr" data-page-slidein="1" data-page-appear="2">
      <div style="position:relative; left:100px; top:40px; color:white; font-size:16pt;">遅れて表示</div>
    </div>
    
    <div class="scr page2" data-page-slidein="3" data-page-appear="">
      ページ２
    </div>
    
    <div class="scr" data-page-slidein="3" data-page-appear="4">
      <div style="position:relative; left:190px; top:140px; color:blueviolet; font-size:16pt;">現れる</div>
    </div>
    
    <div class="scr" data-page-slidein="3" data-page-appear="5">
      <div style="position:relative; left:300px; top:40px; color:indianred; font-size:16pt;">テキスト</div>
    </div>
    
    <div class="scr last-page" data-page-slidein="7" data-page-appear="7">
      Last Page
    </div>
[/code]

[このページ](http://www.akita.co.uk/computing-history/)のような動きをまねしてみたものです。

* * *

以下ソースです。

`HEAD`でjQueryと後で記載するcssとjsをロードします。

[code]

        <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
        <script src="js/sample.js"></script>
        <link rel="stylesheet" href="css/style.css"/>
    
[/code]

本体となるHTMLは以下です。  
対象とするには `scr` css-classを指定します。  
コメントにも書きましたが `data-page-slidein`でスライドしてくるタイミング、`data-page-
appear`で画面にフェードインするタイミングを、「何ページ分スクロールしたときか」で指定します。

[code]

    <body>
        <!-- data-page-slidein  何ページ分スクロールすると そのdivがスライドしてくるか -->
        <!-- data-page-appear   divのFadeInが完了するタイミング ： 何ページ分スクロールしたとき不透明になる。ブランクならフェードしない -->
        <div class="scr first-page" data-page-slidein="0" data-page-appear="">
            Index Page
        </div>
    
        <div class="scr page1" data-page-slidein="1" data-page-appear="">
            ページ１
        </div>
    
        <div class="scr" data-page-slidein="1" data-page-appear="2">
            <div style="position:relative; left:100px; top:40px; color:white; font-size:16pt;">遅れて表示</div>
        </div>
    
        <div class="scr page2" data-page-slidein="3" data-page-appear="">
            ページ２
        </div>
    
        <div class="scr" data-page-slidein="3" data-page-appear="4">
            <div style="position:relative; left:190px; top:140px; color:blueviolet; font-size:16pt;">現れる</div>
        </div>
    
        <div class="scr" data-page-slidein="3" data-page-appear="5">
            <div style="position:relative; left:300px; top:40px; color:indianred; font-size:16pt;">テキスト</div>
        </div>
    
        <div class="scr last-page" data-page-slidein="7" data-page-appear="7">
            Last Page
        </div>
    </body>
    
[/code]

cssファイルです。scrクラスの指定が主です。スライドしてくるdivに関しては背景色を指定した方がいいでしょう。

[code]

    body{
        margin:0;
        padding: 0;
    }
    .scr{
        height:100%;
        position:absolute;
        width:100%;
        top:100%;
    }
    
    .page1{
        background-color: #00b3ee;
    }
    
    .page2{
        background-color: #d58512;
    }
    
    .first-page, .last-page{
        background-color: white;
    }
    
[/code]

メインとなるjavascriptです。

スライド表示に関しては ページの高さ×ページ数 を
topとして設定して普通にスクロールされて登場するだけですが、divが画面の一番上まで来たらそれより下にスクロールしてもその位置をキープするようにしています。

`data-page-
appear`に数字を設定しておくと、その数字のページの１ページ前からフェードインしはじめ、スクロールがそのページに達すると完全に不透明になるような処理を入れてあります。つまりフェードする区間は１ページ分です。

[code]

    $(window).load(function(){    
        var height = $(window).height();
        $(".scr").each(function(i,ele) {
            // ページの高さを確定する。
            var $ele=$(ele);
            var page = $ele.attr("data-page-slidein");
            $ele.css("top", height * page);
            $ele.height(height);
        });
    
        $(window).scroll( function(){
            var scrTop = $(this).scrollTop();
            $(window).scrollLeft(0);
    
            $(".scr").each(function(i,ele){
                var $ele = $(ele);
    
                var opaPage= $ele.attr("data-page-appear");
                var page = $ele.attr("data-page-slidein");
    
                if(page * height  < scrTop ) {
                    // 画面内にとどまる処理
                    $ele.css("top", scrTop);
                }
    
                if(opaPage != ""){
                    // 透明度の処理。自分の出現ページが画面に
                    // どの程度表示されているかの割合から求めている。
                    var value = (opaPage*height - scrTop)/height;
                    $ele.css("opacity", 1-value);
                }
            });
        });
    });
    
[/code]


CC BY-SA 4.0
2014-12-12T14:54:34.813
1565
2019-12-26T06:09:31.543
2019-12-26T06:09:31.543
32986
728
1507
answer