33

Bootstraps のドキュメント ( http://getbootstrap.com/javascript/#affix ) で説明されている Affix メソッドを使用したいのですが、スクロールした後にページの上部に固定したいナビゲーション バーのオフセットが異なる場合があります。その上のコンテンツに応じた値。

ナビゲーションバーの例を次に示します。

<div class="navbar navbar-default" data-spy="affix" data-offset-top="200">
  <ul class="nav navbar-nav">
    <li class="active"><a href="#">Link</a></li>
    <li><a href="#">Link 1</a></li>
    <li><a href="#">Link 2</a></li>
  </ul>
</div>

ご覧のとおり、data-offset-topは現在 200 に設定されています。上のコンテンツの高さが 200px の場合、これはうまく機能しますが、上のコンテンツは動的であるため、このナビゲーション バーの上の高さは常に同じではありません。data-offset-top値を動的にするにはどうすればよいですか?

私はそれを行うにはjavascriptの方法を使用する必要があると思いますが、確かです。

4

7 に答える 7

44

jQuery を使用して、上の動的コンテンツの高さを取得できますnavbar。例えば:

$('#nav').affix({
      offset: {
        top: $('header').height()
      }
}); 

実際のデモ: http://bootply.com/69848

場合によっては、いつ要素を「固定解除」するかを決定するために、offset.bottom も計算する必要があります。ここに接辞-底の例があります

于 2013-09-09T16:39:56.110 に答える
21

カスタム計算を行い、目的の接辞の上の要素の高さからオフセットを構築するたびに、これが機能する方法に完全に不満を感じていました。

これが最高の接辞です。

通常のブーストラップ接辞では、アイテムの自然なオフセットの上部位置が考慮されないため、属性として手動で渡す必要があります。これはそれを処理し、ウィンドウのサイズ変更時にオフセット上部が変更されることを考慮します。

var $attribute = $('[data-smart-affix]');
$attribute.each(function(){
  $(this).affix({
    offset: {
      top: $(this).offset().top,
    }
  })
})
$(window).on("resize", function(){
  $attribute.each(function(){
    $(this).data('bs.affix').options.offset.top = $(this).offset().top
  })
})

これもcode reviewに投稿しました。

data-smart-affix接辞要素に属性を追加することを忘れないでください

このサンプル コードを試してください: https://jsfiddle.net/NabiKAZ/qyrauogw/
(このサンプルでは、​​赤いセクションの高さは、ウィンドウの幅の違いで 100px または 200px または 300px になる可能性があるためdata-offset-top、スクロール時に異なる必要があります。)

于 2015-03-19T15:43:31.287 に答える
3

ThomasReggi の data-smart-affix は、いくつかのまれなケース (ドキュメントのサイズを変更するとき、または添付された列が高すぎるとき) では機能しませんでした。しかし、それは私に簡単なアイデアを与えました: 添付されたコンテンツの前に空の要素を追加し、それを使用してオフセットを取得します。サイズ変更時にうまく機能します。

同時に、要素の幅を元の親の自然な幅に設定しました。これが私の解決策です:

$('[data-affix-after]').each( function() {
  var elem = $(this);
  var parent_panel = elem.parent();
  var prev = $( elem.data('affix-after') );

  if( prev.length != 1 ) {
    /* Create a new element immediately before. */
    prev = elem.before( '<div></div>' ).prev();
  }

  var resizeFn = function() {
      /* Set the width to it's natural width in the parent. */
      var sideBarNavWidth = parent_panel.width()
          - parseInt(elem.css('paddingLeft'))
          - parseInt(elem.css('paddingRight'))
          - parseInt(elem.css('marginLeft'))
          - parseInt(elem.css('marginRight'))
          - parseInt(elem.css('borderLeftWidth'))
          - parseInt(elem.css('borderRightWidth'));
      elem.css('width', sideBarNavWidth);

      elem.affix({
          offset: {
              top: prev.offset().top + prev.outerHeight(true),
              bottom: $('body>footer').outerHeight(true)
          }
      });
  };

  resizeFn();
  $(window).resize(resizeFn);
});

それに付随する HTML は次のとおりです。

<div id='before-affix'></div><!-- leave this empty -->
<div data-affix-after='#before-affix'>
    Put content to affix here.
</div>

また

<div data-affix-after='#create'><!-- any ID that doesn't exist -->
    Put content to affix here.
</div>

必要な CSS は次のとおりです。

.affix { top: 0px },
.affix-bottom { position: absolute; }

接辞を無効にしたい場合 (右の列が積み上げられている場合など)、CSS を使用します。

.affix, .affix-bottom { position: static; }

適切なメディアクエリ内。

GI

于 2015-09-04T12:38:11.777 に答える
1

貼り付けられた div の周りにラッパーを追加することをお勧めします - 貼り付けられたナビゲーション バーでの「スクロール ジャンプ」を避けるためです。トーマスは素晴らしい解決策を投稿しましたが、接辞の後に折りたたまれたスペースが含まれておらず、使用する必要がある 2.x ブーストラップ バージョンでは機能しません。そこで、接辞の完全に新しい実装を作成することにしました。ブーストラップは必要ありません。jquery だけです。これは私の最初の JavaScript です。ブートストラップなしで解決策があることは常に素晴らしいことです

function myaffix() {

var affixoffset = $('.navbar').offset().top

$('#nav-wrapper').height($(".navbar").height());

$(window).scroll(function () {

    if ($(window).scrollTop() <= affixoffset) {
        $('.navbar').removeClass('affix');
    } else {
        $('.navbar').addClass('affix');
    }
});

};

$(document).ready(function () {

   myaffix();

   $(window).on("resize", function () {
       myaffix();
   });

});

ここで例を見つけることができます: http://jsfiddle.net/3ss7fk92/

于 2015-04-16T16:54:33.047 に答える
0

上記のスケリーは正しく、これ以上の方法はありません。「ネイティブ」ブートストラップで可能な唯一の解決策は、JavaScript 呼び出しで接辞オプションをアタッチすることです (上記のhttps://stackoverflow.com/a/18702972/2546679で説明したように)。

同じ効果を達成するために属性を使用することは特に不可能data-offsetです (たとえこれがはるかに便利であったとしても、http://getbootstrap.com/2.3.2/javascript.html#affix の Affix のドキュメントが発生したとしても)そうすることができれば幸いです)。

だから人は書くことができます

data-offset='{"top":42}'

ただし、次のように書くことは許可されていません。

data-offset='{"top":$("#banner").height()}'

その理由は、.data()純粋な JSON 値のみを解析できる JQuery API を介してデータ属性が解析されるためです。 https://api.jquery.com/data/を参照してください。

于 2015-06-14T10:49:04.940 に答える
0

以前はこれで多くの問題を抱えていましたが、何らかの理由で、他の人が提案した解決策を得ることができませんでした。私は Bootstrap と JQuery に比較的慣れていないので、おそらく私がキャッチしていない奇妙なことをしていたのでしょう。とにかく、Bootstrap が意図するように接辞機能を厳密に使用するわけではありませんが、非常にうまく機能するソリューションを見つけました。#thisElement.affix {top: desiredFixedPosition;}CSS はそのまま残しましたが、# thisElement の HTML タグからdata-spyand属性を削除しました。data-offset-top次に、これを JQuery でハードコーディングしました。

var newAffix = function() {
    if($("otherElementsAboveThisElement").height() <= $(window).scrollTop()) {
        $("#thisElement").addClass("affix");
    } else {
        $("#thisElement").removeClass("affix");
    }
}

$(document).ready(function() {
    $(window).resize(newAffix);
    $(window).scroll(newAffix);
}

私がテストした限り、これはページのサイズ変更やスクロールに関係なく機能し、$(document).ready()関数で呼び出す方法を工夫すれば、高さのアニメーション中にメニューを正しい位置に保つことさえできます. 述べたように、これは技術的には完全に「Bootstrap 承認済み」のソリューションではありませんが、Bootstrap サイトに十分に統合されているため、一部で機能するはずです:)

于 2017-10-18T03:46:16.007 に答える