6

私が取り組んでいるサイトで、Bootstrapドキュメント CSS および JSから直接取得した自動フローティング サブナビゲーション バーを実装しました。1 つのビューにのみ表示されますが、これは Rails ビューであるため、読み込まれるオブジェクトに応じて動的に生成されます。

私が見つけたのは、サブナビゲーション バーの下に表示されるコンテンツが十分に長い場合、サブナビゲーション バーの動作が期待どおりに機能することです。 .

ただし、ページがこれよりも短い場合、サブナビゲーション バーは実際に表示されなくなる前に固定され、かなり耳障りなジャンプが発生します。言うまでもなく、バーがあった場所のスペースを見ることができます。見ることができます。

適切なボディ パディングを考慮して、固定 (メイン) ナビゲーション バーを使用していることを付け加えておきます。

$('.subnav').offset.top返される値に問題があるようです。

jQuery / JSのほうが優れている人は、これを診断して、サブナビゲーションバーがスクロールされて表示されなくなったときにのみ固定されるようにする方法を考え出すことができますか?

Javascript:

var $win = $(window)
  , $nav = $('.subnav')
  , navTop = $('.subnav').length && $('.subnav').offset().top
  , isFixed = 0
    , $hiddenName = $('.subnav .hide')

processScroll()

$nav.on('click', function () {
  if (!isFixed) setTimeout(function () {  $win.scrollTop($win.scrollTop() - 47) }, 10)
})

$win.on('scroll', processScroll)

function processScroll() {
  var i, scrollTop = $win.scrollTop()
  if (scrollTop >= navTop && !isFixed) {
    isFixed = 1
    $nav.addClass('subnav-fixed')
        $hiddenName.removeClass('hide')
        if (!$('.subnav li').hasClass('active')) {
            $('.subnav li:eq(1)').addClass('active')
        }
  } else if (scrollTop <= navTop && isFixed) {
    isFixed = 0
    $nav.removeClass('subnav-fixed')
        $hiddenName.addClass('hide')
        $('.subnav li').removeClass('active')
  }
}

Replicating Bootstraps main nav and subnav - この質問を見たことがありますが、まだ使用しているため、問題を回避できるとは思いません.offset()

アップデート:

まだ運がありません。navTopページの長さが短くなるにつれて、それでも短くなるように見えますが、これは を使用しているため意味がありませんoffset().top。その方法がどのように機能するかについて、私が得ていないものはありますか?

更新 2

Bootstrap 2.1.0 では、実際のコンポーネントとしてサブナビゲーション バーと、スティッキー動作を処理するための jQuery プラグインが実際に含まれているため、これは解決されるようです。それでも、offset() 関数がそれほど信頼できない理由を理解したいと思います。

4

1 に答える 1

2

また、同じ JS コードを使用して、自分の Web サイトに適用しました (まだ作成中です)。ここにいくつかのコードがあります(動作中)

HTML

<div class="fix_on_top">
    <div class="container">
        <ul class="breadcrumb">
            <li><a href="#">Home</a> <span class="divider">/</span></li>
            <li><a href="#">Packages</a> <span class="divider">/</span></li>
            <li class="active">Professional courses - I am a breadcrumb; I'll fix myself below the top navbar when you scroll the page</li>
        </ul>
    </div>
</div>

レス (CSS)

.fixed_on_top {
    left: 0;
    right: 0;
    z-index: 1020;
    position: fixed;
    top:$navbarHeight;
}

JavaScript

var $window     = $(window),
    $fix_on_top = $('.fix_on_top'),
    fixed_Top   = $('.fix_on_top').length && $('.fix_on_top').offset().top - 40,
    isFixed     = 0;

process_scroll();

// hack sad times - holdover until rewrite for 2.1
$fix_on_top.on('click', function () {
    if (!isFixed) setTimeout(function () {
        $window.scrollTop($window.scrollTop() - 47)
    }, 10);
});

$window.on('scroll', process_scroll);

function process_scroll()
{
    var i, scrollTop    = $window.scrollTop();

    if (scrollTop >= fixed_Top && !isFixed) {
        isFixed         = 1;
        $fix_on_top.addClass('fixed_on_top');
    }
    else if (scrollTop <= fixed_Top && isFixed)
    {
        isFixed         = 0;
        $fix_on_top.removeClass('fixed_on_top');
    }
}

THEADで動作する元のコード(別のWebサイト用)も適応させました(テーブル-ID = "tablesortable"のWebページごとに1つのテーブルがあります)

// Automatically add the class "fix_on_scroll" on #tablesortable's thead
if ($('#tablesortable thead').length)
{
    var thead_cells = new Array();
    $('#tablesortable thead').addClass('fix_on_scroll');
    // Get the width of each cells in thead
    $('#tablesortable thead').find('td, th').each(function(i, v) {
        thead_cells.push($(this).width());
    });
    // Keep same with in tbody and tfoot
    $('#tablesortable tbody tr:first').children('td, th').each(function(i, v) {
        $(this).width(thead_cells[i]);
    });
    $('#tablesortable tfoot tr:first').children('td, th').each(function(i, v) {
        $(this).width(thead_cells[i]);
    });
}

// Fix all elements (with class .fix_on_scroll) just below the top menu on scroll
// (Modified version from homepage of Twitter's Bootstrap - js/application.js)
var $window     = $(window),
$fix_on_scroll  = $('.fix_on_scroll'),
fixed_elem_top  = $('.fix_on_scroll').length && $('.fix_on_scroll').offset().top - 26,
isFixed     = 0;

process_scroll();

// hack sad times - holdover until rewrite for 2.1
$fix_on_scroll.on('click', function () {
    if (!isFixed) setTimeout(function () {$window.scrollTop($window.scrollTop() - 40)}, 10)
});

$window.on('scroll', process_scroll);

function process_scroll()
{
    var i, scrollTop = $window.scrollTop();
    if (scrollTop >= fixed_elem_top && !isFixed)
    {
        isFixed = 1;
        $fix_on_scroll.addClass('fixed_on_scroll');

        // Keep original width of td/th
        if ($fix_on_scroll.is('thead'))
        {
            $fix_on_scroll.find('td, th').each(function(i, v) {
                $(this).width(thead_cells[i]);
            });
        }
    }
    else if (scrollTop <= fixed_elem_top && isFixed)
    {
        isFixed = 0
        $fix_on_scroll.removeClass('fixed_on_scroll')
    }
}

私の(適応された)コードは機能しています。それらを使用できます。

于 2012-08-18T16:38:23.183 に答える