我已经探索了几种方法,但似乎没有一种真正能像我想要的那样工作:
这是我想要的行为的示例,但不是性能/体验(因为行为是使用
scroll
事件实现的,所以并不顺利)。
我还尝试使用 CSS 变换,它会在向下滚动时添加一个类来隐藏导航栏,然后向上滚动删除该类,从而为导航栏隐藏/显示设置动画,但问题是动画速度与滚动脱节速度。
我也尝试过 CSS 粘性位置,但看起来我需要与它提供的相反的内容。
还有其他方法可以让这项工作顺利进行吗?
检查您提供的链接,它似乎按预期工作(您希望它链接到滚动事件,因为您希望它作为“静态”移动)。但是,如果由于滚动事件不一致而在某些系统上出现不稳定,您可以尝试添加持续时间足够小的
transition
属性。请记住,只有在位置属性保持不变时才应启用此功能,否则当从“绝对”更改为“固定”时,由于坐标原点发生变化,它会弄乱事情。
因此您可以添加另一个变量
let changedPosition = false;
,每当您更改position
属性时,您都可以这样做
if (position !== "absolute") {
changedPosition = true;
} else {
changedPosition = false;
}
position = "absolute";
或
if (position !== "fixed") {
changedPosition = true;
} else {
changedPosition = false;
}
position = "fixed";
当你应用这种风格时
navbar.style = `position: ${position}; top: ${navbarTop}px; transitiona: ${
changedPosition ? "none" : "100ms linear"
}`;
喜欢https://codepen.io/gpetrioli/pen/XWVKxNG?editors=0010
您应该尝试一下您提供的过渡属性,我只是在那里放置了一些示例值。
我看过你的问题,我想我找到了一个简单的方法。
通过这个简单的函数,您可以获得用户滚动的像素数量。
window.onscroll = function (e) {
console.log(window.scrollY); // Value of scroll Y in px
};
用户滚动所需的像素数量后,使进度条
fixed top
(或position:fixed;top:0
)
Gabriele Petrioli 给出了一个很好的答案,但“transitiona”一词有一个拼写错误。 这是一个面向性能的代码,带有一些 onScroll 限制和代码改进:
<script>
let throttling = false;
function onScrollThrottled() {
if (!throttling) {
throttling = true;
requestAnimationFrame(() => {
onScroll();
throttling = false;
});
}
}
let navbarTop = 0;
let transition = true;
let position = "absolute";
let lastScrollPosition = 0;
const navbar = document.getElementById("navbar");
function onScroll() {
const currentScrollPosition = window.pageYOffset || document.documentElement.scrollTop;
if (currentScrollPosition <= 0) {
lastScrollPosition = 0;
navbarTop = 0;
if (position !== "absolute") { transition = true; }
else { transition = false; }
position = "absolute";
} else {
if (currentScrollPosition > lastScrollPosition) {
if (position !== "absolute") { transition = true; }
else { transition = false; }
position = "absolute";
let { top, height } = navbar.getBoundingClientRect()
navbarTop = currentScrollPosition + Math.max(top, -height);
} else {
const { top } = navbar.getBoundingClientRect()
if (top >= 0) {
navbarTop = 0;
if (position !== "fixed") { transition = true; }
else { transition = false; }
position = "fixed";
}
}
lastScrollPosition = currentScrollPosition;
}
navbar.style = `position: ${position}; top: ${navbarTop}px; transition: ${ transition ? "none" : "100ms linear" }`;
}
window.addEventListener("scroll", onScrollThrottled, { passive: true });
</script>