web-dev-qa-db-ja.com

スクロールのヘッダーを修正する方法

私はヘッダーを作成し、一度一定量のピクセルにスクロールすると修正され、その場に留まります。

Cssとhtmlだけを使用してこれを行うことはできますか、jqueryも必要ですか?

理解できるように、デモを作成しました。どんな助けも素晴らしいでしょう!

http://jsfiddle.net/gxRC9/4/

body{
    margin:0px;
    padding:0px;
}
.clear{
    clear:both;
}
.container{
    height:2000px;
}
.cover-photo-container{
width:700px;
height: 348px;
margin-bottom: 20px;
background-color:red;
}

.small-box{
    width:163px;
    height:100px;
    border:1px solid blue;
    float:left;
}

.sticky-header{
    width:700px;
    height:50px;
    background:orange;
    postion:fixed;
}
43
Paul Designer

スクロールイベントを実行するには、JSが必要です。これを行う最良の方法は、スクロールが特定のポイントを通過したときに関連するdivに割り当てられる固定位置の新しいCSSクラスを設定することです。

HTML

<div class="sticky"></div>

CSS

.fixed {
    position: fixed;
    top:0; left:0;
    width: 100%; }

jQuery

$(window).scroll(function(){
  var sticky = $('.sticky'),
      scroll = $(window).scrollTop();

  if (scroll >= 100) sticky.addClass('fixed');
  else sticky.removeClass('fixed');
});

フィドルの例: http://jsfiddle.net/gxRC9/501/


編集:拡張例

トリガーポイントが不明であるが、スティッキー要素が画面の最上部に到達するたびにトリガーする必要がある場合は、offset().topを使用できます。

var stickyOffset = $('.sticky').offset().top;

$(window).scroll(function(){
  var sticky = $('.sticky'),
      scroll = $(window).scrollTop();

  if (scroll >= stickyOffset) sticky.addClass('fixed');
  else sticky.removeClass('fixed');
});

拡張フィドルの例: http://jsfiddle.net/gxRC9/502/

105
Coop

Coopの答えを修正しました。例を確認してください FIDDLE これが私の編集です:

$(window).scroll(function(){
  if ($(window).scrollTop() >= 330) {
    $('.sticky-header').addClass('fixed');
   }
   else {
    $('.sticky-header').removeClass('fixed');
   }
});
14
Mobeen Abdullah

Coopがすでにこの質問に答えていることは知っていますが、静的な値に依存するのではなく、ドキュメント内のdivの場所を追跡するバージョンもあります。

http://jsfiddle.net/gxRC9/16/

Javascript

var offset = $( ".sticky-header" ).offset();
var sticky = document.getElementById("sticky-header")

$(window).scroll(function() {

    if ( $('body').scrollTop() > offset.top){
        $('.sticky-header').addClass('fixed');
    } else {
         $('.sticky-header').removeClass('fixed');
    } 

});

CSS

.fixed{
     position: fixed;
    top: 0px;
}
10
Rich

Coopの答えは素晴らしいです。
ただし、jQueryに依存します。依存関係のないバージョンは次のとおりです。

HTML

<div id="sticky" class="sticky"></div>

CSS

.sticky {
  width: 100%
}

.fixed {
  position: fixed;
  top:0;
}

JS
(これは eyelidlessness's answer を使用してVanilla JSのオフセットを見つけます。)

function findOffset(element) {
  var top = 0, left = 0;

  do {
    top += element.offsetTop  || 0;
    left += element.offsetLeft || 0;
    element = element.offsetParent;
  } while(element);

  return {
    top: top,
    left: left
  };
}

window.onload = function () {
  var stickyHeader = document.getElementById('sticky');
  var headerOffset = findOffset(stickyHeader);

  window.onscroll = function() {
    // body.scrollTop is deprecated and no longer available on Firefox
    var bodyScrollTop = document.documentElement.scrollTop || document.body.scrollTop;

    if (bodyScrollTop > headerOffset.top) {
      stickyHeader.classList.add('fixed');
    } else {
      stickyHeader.classList.remove('fixed');
    }
  };
};

https://jsbin.com/walabebita/edit?html,css,js,output

9
RubenSandwich

Rich's answer で構築するだけで、オフセットを使用します。

これを次のように変更しました。

  • Richの例ではvar $stickyは必要ありませんでしたが、何もしていませんでした
  • オフセットチェックを別の関数に移動し、ドキュメントの準備とスクロールで呼び出したため、ページの途中でスクロールしてページが更新されると、スクロールを待たずにすぐにサイズが変更されます引き金

    jQuery(document).ready(function($){
        var offset = $( "#header" ).offset();
        checkOffset();
    
        $(window).scroll(function() {
            checkOffset();
        });
    
        function checkOffset() {
            if ( $(document).scrollTop() > offset.top){
                $('#header').addClass('fixed');
            } else {
                $('#header').removeClass('fixed');
            } 
        }
    
    });
    
6
crdunst

Coopsの答えは良い、簡単な解決策ですが、固定クラスを適用するとページが非常に短くなり、コンテンツが「ジャンプ」します。ページの長さがスクロール距離がヘッダーの高さより短い場合要素の場合、ジャンプしてページの下部が表示されないように見えます。

私が見つけた答えは、固定される要素(私の場合はnav要素)の上にスペーサーdivを追加し、nav要素と同じ高さに設定し、何も表示しないように設定することでした。

.fixedクラスをnavに追加する場合は、.nav-spacer divを表示し、削除する場合は非表示にします。ページの高さが即座に変わるため、期間を0に設定しました。

HTML

<header>the element above the element that will become fixed</header>
<div class="nav-spacer"></div>
<nav></nav>

CSS

nav {
    position: relative;    
    height: 100px;
}
.nav-spacer{
    position: relative;
    height: 100px;
    display: none;
}
.fixed {
    position: fixed;
    top:0;
    left:0;
    width: 100%;
    /* I like to add a shadow on to the fixed element */
    -webkit-box-shadow: 0px 5px 10px 1px rgba(0,0,0,0.25);
    -moz-box-shadow: 0px 5px 10px 1px rgba(0,0,0,0.25);
    box-shadow: 0px 5px 10px 1px rgba(0,0,0,0.25);
}

JavaScript

var stickyOffset = $('nav').offset().top;

$(window).scroll(function(){
    if ($(window).scrollTop() >= stickyOffset){
        $('nav').addClass('fixed');
        //this makes the page length equal to what it was before fixing nav
        $('.nav-spacer').show(0); 
    }
    else {
        $('nav').removeClass('fixed');
        $('.nav-spacer').hide(0);
    }
});
6
Craig Jacobs

輝かしい、純粋なHTML/CSSソリューション

CSS3を使用した2019では、Javascriptを使用せずにこれを実行できます。私は頻繁に次のようなスティッキーヘッダーを作成します。

body {
  overflow-y: auto;
  margin: 0;
}

header {
  position: sticky; /* Allocates space for the element, but moves it with you when you scroll */
  top: 0; /* specifies the start position for the sticky behavior - 0 is pretty common */
  width: 100%;
  padding: 5px 0 5px 15px;
  color: white;
  background-color: #337AB7;
  margin: 0;
}

h1 {
  margin: 0;
}

div.big {
  width: 100%;
  min-height: 150vh;
  background-color: #1ABB9C;
  padding: 10px;
}
<body>
<header><h1>Testquest</h1></header>
<div class="big">Just something big enough to scroll on</div>
</body>
4
ocket8888

または、固定ヘッダーの高さを高さに設定してspanタグを追加し、スティッキーヘッダーの横に挿入します。

$(function() {
  var $span_height = $('.fixed-header').height;
  var $span_tag = '<span style="display:block; height:' + $span_height + 'px"></span>';

  $('.fixed-header').after($span_tag);
});
3
Oni Victor
 $(document).ready(function(){

    var div=$('#header');
    var start=$(div).offset().top;

    $.event.add(window,'scroll',function(){
        var p=$(window).scrollTop();
        $(div).css('position',(p>start)?'fixed':'static');
        $(div).css('top',(p>start)?'0px':'');

    }); 
});

完璧に機能します。

2
arjun

選択したソリューションは、私のページにうまく収まりませんでした。したがって、これはブートストラップで動作するより高度なバージョンです。

javascript

var stickyOffset = $('.sticky-header').offset().top;

$(window).scroll(function () {
    var sticky = $('.sticky-header'),
        scroll = $(window).scrollTop(),
        header = $('.fixed-header-background');
    sticky.each(function() {
        var left = $(this).offset().left;
        $(this).data('left', left);//I store the left offset
    });

    if (scroll >= stickyOffset) {
        sticky.addClass('fixed');
        header.css('display', 'block');
        sticky.each(function() {
            $(this).css('left', $(this).data('left'));//I set the left offset
        });
    } else {
        sticky.removeClass('fixed');
        header.css('display', 'none');
        sticky.each(function () {
            $(this).css('left', '');//I remove the left offset
        });
    }
});

CSS

.fixed-header-background {
    display: none;
     position: fixed;
    top: 50px;
    width: 100%;
    height: 30px;
    background-color: #fff;
    z-index: 5;
    border-bottom-style: solid;
    border-bottom-color: #dedede;
    border-bottom-width: 2px;
}

.fixed{
     position: fixed;
    top: 52px;
    z-index: 6;
}

およびHTML

    <div class="fixed-header-background"></div>
<table class="table table-hover table-condensed">
        <thead>
            <tr>
                <th></th>
                <th><span class="sticky-header">My header 1</span></th>
                <th><span class="sticky-header">My header 2</span></th>
            </tr>
        </thead>
        <tbody>
[....]

        </tbody>
    </table>
2
Daniel

うまくいけば、この代替ソリューションの1つが、他の誰かにとっても私にとって価値があるものになることを願っています。

状況
HTML5ページには、ヘッダー内のnav要素であるメニューがありました(ヘッダーではなく、別の要素のヘッダー)。
ユーザーがスクロールするとナビゲーションを上部に固定したかったのですが、これより前はヘッダーが絶対配置されていました(そのため、他のものを少しオーバーレイすることができました)。
上記のソリューションは絶対に配置された要素であるため、.offsetTopは変更されないため、変更をトリガーしませんでした。さらに、.scrollTopプロパティは、単に最上位要素の最上位でした...つまり、0であり、常に0になります。
[。スクロール中に同じ数字が発生しました)。

解決
私にとっての解決策は

window.visualViewport.pageTop

PageTopプロパティの値は、画面の表示可能なセクションを反映しているため、表示可能な領域の境界を基準にして要素がどこにあるかを追跡できます。
これにより、ウィンドウのスクロールイベントに割り当てられた単純な関数が、ナビゲーションバーの上部が表示可能領域の上部と交差したことを検出し、スタイルを適用して上部に貼り付けることができました。

おそらく言うまでもなく、スクロールを扱うときはいつでも、このソリューションを使用して、スクロールされる要素の動きにプログラム的に応答することを期待しています。
他の人に役立つことを願っています。

0
MER