jjzjj

javascript - Twitter Bootstrap 粘性子导航在它应该在较短的页面上之前变得固定

coder 2025-01-13 原文

我实现了一个自动 float 的子导航栏,直接取自 Bootstrap docs CSS and JS ,在我正在处理的网站中。它只出现在一个 View 中,但这是一个 Rails View ,因此它是根据加载的对象动态生成的。

我发现,当出现在子导航栏下方的内容足够长时,子导航栏的行为会按预期工作 - subnav-fixed 类会在子导航栏滚动时立即添加看不见。

但是,如果页面比这短,子导航栏将在它实际超出 View 之前固定,这会产生非常刺耳的跳转,更不用说您可以看到该栏曾经所在的空间,您应该看不到。

我应该补充一点,我使用的是固定的(主)导航栏,并考虑了适当的主体填充。

问题似乎出在返回的 $('.subnav').offset.top 值上。

谁能更好地使用 jQuery/JS 来帮助诊断这个问题,并想出一种方法使子导航栏仅在滚动到 View 之外时才固定?

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() 函数如此不可靠。

最佳答案

我也采用了相同的 JS 代码,并将其改编到我的网站(仍在 build 中)。这是一些代码(工作)

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 的原始代码(用于另一个网站)(表格 - 我每个网页有一张表格,id = "tablesortable")

// 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')
    }
}

我的(改编的)代码正在运行。您可以使用它们。

关于javascript - Twitter Bootstrap 粘性子导航在它应该在较短的页面上之前变得固定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11380562/

有关javascript - Twitter Bootstrap 粘性子导航在它应该在较短的页面上之前变得固定的更多相关文章

  1. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  2. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  3. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  4. ruby-on-rails - 在所有延迟的作业之前 Hook - 2

    是否可以在所有delayed_job任务之前运行一个方法?基本上,我们试图确保每个运行delayed_job的服务器都有我们代码的最新实例,所以我们想运行一个方法来在每个作业运行之前检查它。(我们已经有了“check”方法并在别处使用它。问题只是关于如何从delayed_job中调用它。) 最佳答案 现在有一种官方方法可以通过插件来做到这一点。这篇博文通过示例清楚地描述了如何执行此操作http://www.salsify.com/blog/delayed-jobs-callbacks-and-hooks-in-rails(本文中描述

  5. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  6. ruby-on-rails - define_method 在调用方法之前不使用变量? - 2

    我无法从for循环中获取变量。似乎i(var)是稍后计算的,而不是我完全需要的类定义。ree-1.8.7-2010.02>classPatree-1.8.7-2010.02?>foriin39..47ree-1.8.7-2010.02?>define_method("a#{i}".to_sym)doree-1.8.7-2010.02>putsiree-1.8.7-2010.02?>endree-1.8.7-2010.02?>endree-1.8.7-2010.02?>end#=>39..47ree-1.8.7-2010.02>p=Pat.new#=>#ree-1.8.7-2010.02

  7. ruby-on-rails - ActiveRecord:除非另有说明,否则在保存之前使所有文本字段都调用 strip - 2

    多年来,我在各种网站上遇到过各种问题,用户在字符串和文本字段的开头/结尾放置空格。有时这些会导致格式/布局问题,有时会导致搜索问题(即搜索顺序看起来不对,但实际上并非如此),有时它们实际上会使应用程序崩溃。我认为这会很有用,而不是像我过去所做的那样放入一堆before_save回调,向ActiveRecord添加一些功能以在保存之前自动调用任何字符串/文本字段上的.strip,除非我告诉它不是,例如do_not_strip:field_x,:field_y或类定义顶部的类似内容。在我去弄清楚如何做到这一点之前,有没有人看到更好的解决方案?明确一点,我已经知道我可以做到这一点:befor

  8. ruby-on-rails - 如何在 Rails 3 中保存到数据库之前格式化值 - 2

    我有一个带有利润字段的用户模型。利润字段是DECIMAL(11,0)类型。我在表单上有一个屏蔽输入,允许用户输入1,000美元之类的内容。我想格式化该值并从中删除除数字以外的所有内容,这样我将保存1000。这是我到目前为止所拥有的:classUser但它一直在数据库中保存0。看起来它在我的格式化函数之前将其转换为十进制。 最佳答案 试试这个:defprofit=(new_profit)self[:profit]=new_profit.gsub(/[^0-9]/,'')end 关于ruby

  9. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  10. ruby-on-rails - Ruby on Rails - 我可以在调用之前修改属性的值吗? - 2

    假设我有一个名为Product的模型,其中有一个名为brand的字段。假设brand的值以this_is_a_brand格式存储。我可以在模型(或其他任何地方)中定义一个方法,允许我在调用brand之前修改它的值吗?例如,如果我调用@product.brand,我想得到ThisisaBrand,而不是this_is_a_brand。 最佳答案 我建议使用方括号语法([]和[]=)而不是read_attribute和write_attribute。方括号语法更短并且designedtowraptheprotectedread/writ

随机推荐