naritoブログ

このブログはDjangoとBootstrap4で作成されました
ソースコード

Bootstrapで、スクロールしてくる要素(カクカク追従)②

プログラミング関連 Bootstrap3 約555日前
2016年5月15日16:21
以前に、navbarとheaderを追従させる方法を書きました。
http://torina.top/detail/173/

今回は以下のデモのような、スクロールする毎にカクカク追従するnavbar等を作ります。
http://torina.top/media/html/test_87H9io1.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>追従</title>
 
    <!-- Bootstrap -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style>
    #nav {
      position: absolute;
      width: 100%;
    }
    #contents {
      height: 3000px;
    }
    </style>
  </head>
  <body>
    <nav class="navbar navbar-inverse" id="nav">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">ナビバー</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <ul class="nav navbar-nav">
            <li><a href="#">Home</a></li>
            <li><a href="#">About</a></li>
            <li><a href="#">Info</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <section id="contents"></section>
    
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
      <script type="text/javascript">

      $(function() {
          var offset = $("#nav").offset().top;  // 追従させたい対象のtopを。
          var topPadding = 0;  // 追従する際、上にどのぐらい余白をあけるか。余白なしなら0

          // スクロール時のイベント
          $(window).scroll(function() {
              if ($(window).scrollTop() > offset) {
                  $("#nav").stop().animate({
                      marginTop: $(window).scrollTop() - offset + topPadding
                  });
              } else {
                  $("#nav").stop().animate({
                      marginTop: 0
                  });
              };
          });
      });
      </script>
  </body>
</html>


元々のnavbar部分です。
    <nav class="navbar navbar-inverse" id="nav">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">ナビバー</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <ul class="nav navbar-nav">
            <li><a href="#">Home</a></li>
            <li><a href="#">About</a></li>
            <li><a href="#">Info</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>


今回は、position:absoluteが必要になります。width100%等の幅の指定は、必要に応じて指定します。
#contentsは、縦長にしないとスクロールできないので作っただけです。
    <style>
    #nav {
      position: absolute;
      width: 100%;
    }
    #contents {
      height: 3000px;
    }
    </style>


追従は、今回jsを使いました。
      <script type="text/javascript">

      $(function() {
          var offset = $("#nav").offset().top;  // 追従させたい対象のtopを。
          var topPadding = 0;  // 追従する際、上にどのぐらい余白をあけるか。余白なしなら0

          // スクロール時のイベント
          $(window).scroll(function() {
              if ($(window).scrollTop() > offset) {
                  $("#nav").stop().animate({
                      marginTop: $(window).scrollTop() - offset + topPadding
                  });
              } else {
                  $("#nav").stop().animate({
                      marginTop: 0
                  });
              };
          });
      });
      </script>


更に、Bootstrapのモーダル(Modal)もカクカク追従させてみましょう。
デモページは、こちら
http://torina.top/media/html/test_rosqWBe.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>追従</title>
    <!-- Bootstrap -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style>    
    #contents {
        height: 3000px;
    }
    
    body.modal-open {
        overflow: scroll;
    }
    
    .modal {
        position: absolute;
        width: 100%;
        height: 100%;
    }
    </style>
</head>

<body>
    <a href="#my-modal" data-toggle="modal">モーダル表示</a>
    <section id="contents"></section>
    
    <!-- モーダルの設定です -->
    <div class="modal fade" id="my-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-body">
                    <h1>モーダルです</h1>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div><!-- /modal -->
    
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <script type="text/javascript">
    
    $(function() {
        var offset = 15;   // 追従させたい対象のtopを。
        var topPadding = 15; // 追従する際、上にどのぐらい余白をあけるか。余白なしなら0

        // スクロール時のイベント
        $(window).scroll(function() {
            if ($(window).scrollTop() > offset) {
                $(".modal").stop().animate({
                    marginTop: $(window).scrollTop() - offset + topPadding
                });
            } else {
                $(".modal").stop().animate({
                    marginTop: 0
                });
            };
        });
    });
    </script>
</body>

</html>


これはモーダル表示時に、bodyにスクロールバーをつけています。
これがないと、モーダル表示時にスクロールはできないように思います。詳しくは調べて、ないのだけど
    body.modal-open {
        overflow: scroll;
    }



デフォルトのモーダルは、position:fixedです。
今回のようにカクカク追従させるならば、absoluteを指定する必要があります。
    .modal {
        position: absolute;
        width: 100%;
        height: 100%;
    }


モーダルを呼び出すリンクと、モーダルダイアログです。
    <a href="#my-modal" data-toggle="modal">モーダル表示</a>
    <section id="contents"></section>
    
    <!-- モーダルの設定です -->
    <div class="modal fade" id="my-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-body">
                    <h1>モーダルです</h1>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div><!-- /modal -->


先ほどと同じ、カクカク追従させるjsです。やっぱ汎用的なんすね~
var offsetと、topPaddingは色々試すとよいでしょう。
    <script type="text/javascript">
    
    $(function() {
        var offset = 15;   // 追従させたい対象のtopを。
        var topPadding = 15; // 追従する際、上にどのぐらい余白をあけるか。余白なしなら0

        // スクロール時のイベント
        $(window).scroll(function() {
            if ($(window).scrollTop() > offset) {
                $(".modal").stop().animate({
                    marginTop: $(window).scrollTop() - offset + topPadding
                });
            } else {
                $(".modal").stop().animate({
                    marginTop: 0
                });
            };
        });
    });
    </script>


ちなみにですが、カクカク追従させなくてもfixed状態でいいならば、以下のようになります。
デモページ
http://torina.top/media/html/test_NTnZsQ5.html

通常のmodalに、overflow: scroll;をつけただけです。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>追従</title>
    <!-- Bootstrap -->
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style>    
    #contents {
        height: 3000px;
    }
    
    body.modal-open {
        overflow: scroll;
    }
    
    </style>
</head>

<body>
    <a href="#my-modal" data-toggle="modal">モーダル表示</a>
    <section id="contents"></section>
    
    <!-- モーダルの設定です -->
    <div class="modal fade" id="my-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-body">
                    <h1>モーダルです</h1>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div><!-- /modal -->
    
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</body>

</html>