前回、スティッキーの基本を学習したが、今回はそれの応用だ。画面に常駐させるのは便利である反面、画面を占有してしまうデメリットがある。画面の小さいノートパソコンで閲覧していると邪魔に感じることも少なくない。そこで常駐させる際にサイズを縮めてあげるバージョンの作成を行う。それと合わせて、スクロールイベントなどの発生回数の極端に多いイベント処理を間引く方法も覚えよう。

準備

1.Lesson05で作成したフォルダを複製してLesson06とする。前回のフォルダがない人は下からダウンロードし、リネームする。


2.非常に発生回数の多いscrollやresizeイベントをなんのケアもしないで利用すると、処理がとても重くなってしまうので間引く処理をいれる。今回はプラグインで対応する。以下をダウンロードして、解凍しjs/vendorフォルダにおく。

3.プラグインを読み込み処理をいれる。index.htmlを以下のように編集する。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>タイトル</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="css/normalize.css">
  <link rel="stylesheet" href="css/main.css">
</head>
<body>
  <div id="container">
    <header><img src="images/slide-1.jpg"></header>
    <div id="navBox">
      <div id="logo"><a href="#">joytas.net</a></div>
      <ul>
        <li><a href="#">Menu1</a></li>
        <li><a href="#">Menu2</a></li>
        <li><a href="#">Menu3</a></li>
        <li><a href="#">Menu4</a></li>
      </ul>
    </div>
    <main>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
    </main>
    <footer>
      &copy;joytas.net
    </footer>
  </div>
  <script src="js/vendor/jquery-1.12.4.min.js"></script>
  <script src="js/vendor/jquery-ui-1.12.1.min.js"></script>
  <script src="js/vendor/jquery.easing.1.3.js"></script>
  <!--下の一行を追加-->
  <script src="js/vendor/jquery.ba-throttle-debounce.min.js"></script>
  <script src="js/main.js"></script>
</body>
</html>

4.main.cssを以下のように編集する。

#container{
  position: relative;
  width:960px;
  margin:0 auto;
}
header img{
  /*画像の下部に隙間が出るのをfix*/
  display: block;
}
#navBox{
  width:960px;
  box-sizing: border-box;
  /*absoluteにして、top,leftなどの指定をしないとその場所に絶対配置される*/
  position: absolute;
  height:50px;
  background:#333;
  color:white;
  padding:0 50px;

}

#navBox #logo{
  margin: 0;
  font-size:20px;
  font-weight: bold;
  float:left;
}
#navBox #logo a{
  text-decoration: none;
  line-height:50px;
  color:#eee;
}
#navBox ul{
  float:right;
}
#navBox ul li{
  display: inline-block;
  margin-right:30px;
}

#navBox ul li a{
  color:white;
  text-decoration: none;
}
#navBox ul li a:hover{
  text-decoration: underline;
}

/*以下を追加*/
#cloneWrapper{
  position:fixed;
  top:-100px;
  width:960px;
  height:30px;
  z-index:10;
  transition: 0.5s;
  left: 50%;
  margin-left:-480px;
}
#cloneWrapper #navBox{
height:30px;
}
#cloneWrapper #navBox #logo{
  font-size:14px;
}
#cloneWrapper #navBox #logo a{
  line-height:30px;
}
#cloneWrapper #navBox ul{
  margin:0;
}
#cloneWrapper #navBox ul li{
  line-height: 30px;
  font-size:14px;
}

#cloneWrapper.sticky{
  top:0;
}
/***********************/
main{
  background: #ddd;
  padding:70px 50px 50px;
}

main p{
  margin-bottom:50px;
}
footer{
  background: #333;
  color:#ddd;
  text-align: center;
  line-height: 40px;
  height:40px;
}


5.main.jsを以下のように編集。

$(function(){
  //windowオブジェクトをjQueryにしてキャッシュ
  var $window=$(window);
  //navBoxオブジェクトをjQueryにしてキャッシュ
  var $navBox=$('#navBox');
  //#navBox要素の複製をメモリ上に作成
  var $navBoxClone=$navBox.clone();
  //新規に要素をメモリ上に作成
  var $cloneWrapper=$('<div id="cloneWrapper"></div>');
  //ラッパー要素の子要素にクローンを追加(メモリ上)
  $cloneWrapper.append($navBoxClone);
  //#containerの要素にラッパー要素を配置(ここではじめて実際に配置される)
  $('#container').append($cloneWrapper);
  //offset().topでドキュメントの上からの距離を取得、outerHeight()で要素の高さを取得
  var changePoint=$navBox.offset().top+$navBox.outerHeight();
  //スクロール処理をプラグインを使って200msごとに1回の処理にする
  $window.on('scroll',$.throttle(200,function(){
    //スクロール位置がchangePointより大きくなったら
    if($window.scrollTop()>changePoint){
      //クラスを付与
      $cloneWrapper.addClass('sticky');
    }else{
      //クラスを削除
      $cloneWrapper.removeClass('sticky');
    }
  }));
$window.trigger('scroll');
});


6.確認してみよう。最初のnavBoxが消えると同時に小さくなったnavBoxが上部に固定されて表示されれば成功だ。
[解説]
ドキュメントを読み込むと同時にnavBoxのクローンを作成し、それをラップする要素に入れることによってcssを分岐させている。
クローン作成や、jQueryによる要素の作成などもできるようになっておくと、デザイナーさんのわがままな注文にも笑顔で対応できるようになるので慣れておこう。またスクロール処理を間引く処理も大切だ。この処理を入れないとスマホなどでは挙動がおかしくなったり端末が高温になったりする場合もある。