jquery - 如何修复折叠到导航栏的故障标题

标签 jquery html css header navigation

我正在尝试创建一个标题,它会在您向下滚动时慢慢折叠成导航栏(标题的高度会随着您向下滚动而降低,直到达到 70 像素的高度,此时它会粘在导航栏的顶部屏幕)。
我已经设法实现了这一点,但是它非常有问题,而且它可能不是处理它的“最干净”的方式......这就是我所做的:http://www.stroba.uk .
如您所见,它有很多故障并且一点也不流畅。 我还为我正在尝试做的事情创建了一个简化的 jsfiddle:http://jsfiddle.net/uvwusfy2/ .
有谁知道我该如何解决这个“故障”?是采用不同的方式还是改进我的方式?

如果我的做法让你感到困惑,这里有一个解释:

HTML

<div class="Container">
    <div class="space"></div>
    <div class="header">
        This is the header that should turn into a nav bar as you scroll down to where it has a height of 70px
    </div>
    <div class="content">
        This is some content...<br>
        This is some content...<br>
        This is some content...<br>
        This is some content...<br>
        This is some content...<br>
        This is some content...<br>
        This is some content...<br>
    </div>
</div>

我在这里创建标题、内容和一个空格 div,稍后我将使用 jQuery 填充它们。

CSS

div.Container {
color:white;
font-family:arial;
}
div.space {
    width:100%
    height:0px;
}
div.header {
    height:300px;
    width:100%;
    background: linear-gradient(
      to bottom,
      #5d9634,
      #5d9634 50%,
      #538c2b 50%,
      #538c2b
    );
    background-size: 100% 20px;
}
div.header nav {
    position:absolute;
    bottom:0;
    right:0;
}
div.content {
    height: 1500px;
    background-color:blue;
    background: repeating-linear-gradient(
      45deg,
      #606dbc,
      #606dbc 10px,
      #465298 10px,
      #465298 20px
    );
}

jQuery

$(function() {
    var initialHeaderHeight = $("div.header").height();
    $(window).scroll(function(event) {
        var st = $(window).scrollTop();
        var headerHeight = $("div.header").height();
        if (st < initialHeaderHeight - 70) {
            $("div.header").height(initialHeaderHeight - $(window).scrollTop());
            $("div.space").height($(window).scrollTop());
            $("div.header").css("position", "relative");
            $("div.content").css("top", "0");
        } else {
            $("div.header").css("position", "fixed");
            $("div.header").css("top", "0");
            $("div.content").css("top", "70px");
        }
    })
});

在这里,我这样做是为了当用户向下滚动页面时,标题变小,“空间”div 变大并占用标题在用户向下滚动之前占用的空间,这样看起来比如内容向上滚动,标题变小。
很抱歉,这可能难以理解,但我只想知道是否有任何方法可以改进代码,以便向下滚动页面的过程更加顺畅,故障更少。

最佳答案

作为一般规则,您希望尽可能少地调用 jQuery,以避免性能瓶颈。

每次 $(window).scroll 事件触发时,您的代码都会重复查找 DOM - 这在用户滚动时经常发生。每次调用 jQuery 函数时,比如说 $('div.header'),jQuery 必须查找整个文档以检索元素 (div.header) .这是一个缓慢的步骤,需要在修改元素的 CSS 属性之前完成。

要优化您的代码,请在加载 DOM 时一次性检索对 .header.space.content 元素的引用,存储它们,并在您的动画调用中使用它们。您可以在下面看到这个和其他一些优化:

$(function () {
    // retrieve and store header, space and content:
    var $header = $('div.header'),
        $space = $('div.space'),
        $content = $('div.content'),
        initialHeaderHeight = $header.height(),
        // declare variables to use in the event handler,
        // to avoid redeclaring them at every call:
        st,
        headerHeight;

    $(window).scroll(function (event) {
        st = $(window).scrollTop();
        headerHeight = $header.height();
        if (st < initialHeaderHeight - 70) {
            // reuse the $space, $header, $content, and st values, 
            // to avoid repeated $("") and $(window).scrollTop() calls:
            $header.height(initialHeaderHeight - st);
            $space.height(st);
            $header.css("position", "relative");
            $content.css("top", "0");
        } else {
            // reuse $header and $content to avoid
            // repeated $("") calls, and
            // use alternative .css() syntax to eliminate
            // additional .css() call on $header:
            $header.css({
                position: "fixed",
                top: 0
            });
            $content.css("top", "70px");
        }
    });
});

更新:

进一步的改进是让 .header 始终锚定在视口(viewport)的顶部,根据滚动值调整它的高度,并使用 .space 元素仅在滚动时定位 .content

首先,给你的标题固定位置:

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

接下来,当页面加载时,将间隔元素的高度设置为页眉的初始高度。当用户滚动时,间隔符将按照您需要的方式定位内容元素:

$space.height(initialHeaderHeight);

最后,根据当前滚动位置更新标题的高度:

$(window).scroll(function (e) {
    st = e.delegateTarget.scrollY; // get scrollDiff from scroll event
    if (st < initialHeaderHeight - 70) {
        headerHeight = initialHeaderHeight - st;
    } else {
        headerHeight = 70;
    }
    $header.height(headerHeight);
});

Updated Fiddle

关于jquery - 如何修复折叠到导航栏的故障标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31419124/

相关文章:

jquery - 为某个类强制使用 jquery 的 css

javascript - 在 Bootstrap Accordion 面板中预期之前触发 Mouseout

jquery - 在 Grails REST 中使用 params 获取 JSON 对象

html - 如何调整两个div的偏移量?

javascript - 更改按钮样式不起作用

javascript - 简单的 jQuery 计数计时器请帮忙

javascript - 覆盖 iframe 内容 css

javascript - `ie9` - 父级可编辑时 contenteditable false 不工作

html - 有没有办法调整 &lt;input type ="label">?

css - jquery 数据表自定义标题悬停样式