見出し画像

『jQuery 最高の教科書』めも④-スティッキーヘッダー


流れ

  1. ヘッダーのデフォルトの位置を保存する

  2. ウィンドウのスクロール量を常に監視する

  3. ウィンドウのスクロール量がヘッダーのデフォルトの位置を超えた場合は、ヘッダーをスティッキー配置にする

  4. ウィンドウのスクロールが画面上部まで戻ったら、ヘッダーをデフォルトの位置に戻す

offset()

jQuery要素のドキュメント上の位置を取得するメソッド
プロパティはtop leftの2つ
ex.) $header.offset().top

on()

特定の出来事が起こるタイミングに実行したい命令 p52

scrollTop()

縦方向にどれだけスクロールされたのかを調べるメソッド

trigger()

任意のイベントを発生させるメソッド
$window.trigger('scroll');
画面の途中までスクロールした状態でリロード、特定のidにアクセスしたりなどユーザーがスクロールしていないがスティッキーした状態であるべき状況において動作させるため。

自分で書いてみる

ヒント

// ウィンドウを jQuery オブジェクト化
// ヘッダーを jQuery オブジェクト化
// ヘッダーのデフォルト位置を取得 headerOffsetTop

        // ウィンドウのスクロールイベントを監視
        // (ウィンドウがスクロールするごとに処理を実行する)
        
            // ウィンドウのスクロール量をチェックし、
            // ヘッダーのデフォルト位置を過ぎていればクラスを付与、
            // そうでなければ削除
            
        // ウィンドウのスクロールイベントを発生させる
        // (ヘッダーの初期位置を調整するため)

contents()

対象の子要素ぜんぶを選択するメソッド

clone()

選択した要素の複製を作り出すメソッド

outerHeight()

要素の高さを求めるメソッド
padding borderも含むがouterHeight(true)とするとmarginも含む

append()

引数に指定された要素をjQueryオブジェクトに挿入するメソッド

appendTo()

$('#outer').append($('#innder')); outerinnerを入れる

&('#inner').appendTo($('#outer')); innerouterに入れる 

throttling

1スクロール1スクロールイベントハンドラを実行していたらサーバーを重くするからある程度実行頻度を落とすことで負担を減らす
1秒間に15回以上は実行されなくなる
$window.on('scroll', $.throttle(1000 / 15, function (){

自分で書いてみる

//.page-headerの要素各々に処理をしていくよ
//変数を作っていく
// WindowをjQueryオブジェクトに
// ヘッダーをjQueryオブジェクトに

// 架空のヘッダークローンjQueryオブジェクトをつくる
// 架空のヘッダークローンのコンテナーjQueryオブジェクトをつくる

// HTML の上辺からヘッダーの底辺までの距離 = ヘッダーのトップ位置 + ヘッダーの高さ

//処理をしていく
// コンテナーにヘッダーのクローンを挿入
// コンテナーを body の最後に挿入

// スクロール時に処理を実行するが、回数を 1 秒間あたり 15 までに制限
//もしスクロール量がしきい値より大きかったら
//小さかったら
        // スクロールイベントを発生させ、初期位置を決定
$(function(){
    $('.page-header').each(function () {
        var $window = $(window),
            $header = $(this),
            $headerClone = $header.contents().clone(),
            $headerCloneContainer = $('<div class="page-header-clone"></div>'),
            threshold = $header.offset().top + $header.outerHeight();

        $headerCloneContainer.append($headerClone);
        $headerCloneContainer.appendTo('body');

        $window.on('scroll', $.throttle(1000 / 15, function () {
            if ($window.scrollTop() > threshold) {
                $headerCloneContainer.addClass('visible');
            } else {
                $headerCloneContainer.removeClass('visible');
            }
        }));
        $window.trigger('scroll');
    });
    
});

いいなと思ったら応援しよう!