如何修复折叠到导航栏的故障 header
How to fix a glitchy header collapsing to nav bar
我正在尝试创建一个 header,它会在您向下滚动时慢慢折叠成导航栏(header 的高度会随着您向下滚动而降低,直到达到 70 像素的高度, 当它粘在屏幕顶部时)。
我已经设法实现了这一点,但是它非常小故障并且可能不是 "cleanest" 处理它的方式......这就是我所做的:http://www.stroba.uk .
如您所见,它有很多故障并且一点也不流畅。
我还为我正在尝试做的事情创建了一个简化的 jsfiddle:http://jsfiddle.net/uvwusfy2/ .
有谁知道我该如何解决这个 "glitchiness"?是采用不同的方式还是改进我的方式?
如果我这样做的方式让你感到困惑,这里有一个解释:
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>
我在这里创建 header、内容和 space 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");
}
})
});
在这里,我这样做是为了当用户向下滚动页面时,header 变小,"space" div 变大并占据 space header 在用户向下滚动之前占据了,因此看起来内容向上滚动并且 header 变小了。
很抱歉,这可能很难理解,但我只是想知道是否有任何方法可以改进代码,以便向下滚动页面的过程更加顺畅,故障更少。
作为一般规则,您希望进行尽可能少的 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
始终锚定在视口的顶部,根据滚动值调整它的高度,并仅使用 .space
元素定位 .content
滚动时。
首先,给出你的header固定定位:
div.header {
position: fixed;
top: 0;
}
接下来,当页面加载时,将间隔元素的高度设置为 header 的初始高度。当用户滚动时,间隔符将按照您需要的方式定位内容元素:
$space.height(initialHeaderHeight);
最后,根据当前滚动位置更新 header 的高度:
$(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);
});
只需要为 transition
添加适当的 CSS 规则,如下所示:
div.header {
height:300px;
width:100%;
background: linear-gradient(
to bottom,
#5d9634,
#5d9634 50%,
#538c2b 50%,
#538c2b
);
transition: height 500ms; //Add this line
background-size: 100% 20px;
}
希望这就是您所期待的。
我正在尝试创建一个 header,它会在您向下滚动时慢慢折叠成导航栏(header 的高度会随着您向下滚动而降低,直到达到 70 像素的高度, 当它粘在屏幕顶部时)。
我已经设法实现了这一点,但是它非常小故障并且可能不是 "cleanest" 处理它的方式......这就是我所做的:http://www.stroba.uk .
如您所见,它有很多故障并且一点也不流畅。
我还为我正在尝试做的事情创建了一个简化的 jsfiddle:http://jsfiddle.net/uvwusfy2/ .
有谁知道我该如何解决这个 "glitchiness"?是采用不同的方式还是改进我的方式?
如果我这样做的方式让你感到困惑,这里有一个解释:
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>
我在这里创建 header、内容和 space 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");
}
})
});
在这里,我这样做是为了当用户向下滚动页面时,header 变小,"space" div 变大并占据 space header 在用户向下滚动之前占据了,因此看起来内容向上滚动并且 header 变小了。
很抱歉,这可能很难理解,但我只是想知道是否有任何方法可以改进代码,以便向下滚动页面的过程更加顺畅,故障更少。
作为一般规则,您希望进行尽可能少的 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
始终锚定在视口的顶部,根据滚动值调整它的高度,并仅使用 .space
元素定位 .content
滚动时。
首先,给出你的header固定定位:
div.header {
position: fixed;
top: 0;
}
接下来,当页面加载时,将间隔元素的高度设置为 header 的初始高度。当用户滚动时,间隔符将按照您需要的方式定位内容元素:
$space.height(initialHeaderHeight);
最后,根据当前滚动位置更新 header 的高度:
$(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);
});
只需要为 transition
添加适当的 CSS 规则,如下所示:
div.header {
height:300px;
width:100%;
background: linear-gradient(
to bottom,
#5d9634,
#5d9634 50%,
#538c2b 50%,
#538c2b
);
transition: height 500ms; //Add this line
background-size: 100% 20px;
}
希望这就是您所期待的。