Javascript 固定导航栏偏移的平滑滚动
Javascript smooth scrolling with fixed navbar offset
我找到了这个 javascript 平滑滚动的代码
window.smoothScroll = function(target) {
var scrollContainer = target;
do { //find scroll container
scrollContainer = scrollContainer.parentNode;
if (!scrollContainer) return;
scrollContainer.scrollTop += 1;
} while (scrollContainer.scrollTop == 0);
var targetY = 0;
do { //find the top of target relatively to the container
if (target == scrollContainer) break;
targetY += target.offsetTop;
} while (target = target.offsetParent);
scroll = function(c, a, b, i) {
i++; if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function(){ scroll(c, a, b, i); }, 20);
}
// start scrolling
scroll(scrollContainer, scrollContainer.scrollTop, targetY, 0);
}
并变得简单 example here。
如您所见,它正在滚动到红色部分,但不排除导航栏的高度。红色部分的开头一直到页面顶部,在导航栏下。
如何向该脚本添加偏移量,以便在点击导航栏时红色部分停止?填充不是一个选项,我已经尝试过了,但看起来不太好。我也需要这个在香草 javascript,而不是 jquery.
提前致谢!
看看这个,它计算 header 的高度,然后从滚动位置中减去它:
header = document.querySelectorAll('.navbar'),
space = header[0].clientHeight;
...
var targetY = -space;
更新 - 在评论中请求功能以重新定义偏移量。为此,我将 targetY
设为全局变量,它可以通过执行一个函数来取消更新。因此,在 class 在滚动时切换的脚本中,在那之后只需添加一行 headerSpace();
,它将重新计算高度。根据我的阅读,最初的 class 也仍然存在,因此它应该无需任何进一步调整即可工作。
按钮上的内联脚本也被删除并制作成事件侦听器...
最终版本 - requestAnimationFrame
的实施将使动画更流畅,在 CPU 上也更容易。当该功能不可用时,保留原始功能作为后备。可以使用顶部的变量设置持续时间(600 毫秒现在匹配之前设置的 20 毫秒的 30 个步骤)。还认为将 header 高度检查放在按钮单击事件处理程序中可能很方便。所以它总是在用户激活滚动动画时重新计算(并且不再需要将它直接挂接到切换 class 中):
duration = 600
基本代码:
scroll = function(c, a, b, i) {
if (modern) {
var present = Date.now(),
elapsed = present-initial,
progress = Math.min(elapsed/duration, 1);
c.scrollTop = a + (b - a) * progress;
if (progress < 1) requestAnimationFrame(function() {
scroll(c, a, b, i);
});
}
else {
i++; if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function() {scroll(c, a, b, i)}, 20);
}
}
作为旁注,第一次单击按钮时它可能看起来很突然,但这是因为 Codepen。我怀疑焦点在 window 上,其中包含脚本,而不是内容本身。因此 window 必须首先 'wake up',requestAnimationFrame
的节能方面。当首先单击内容内的其他任何地方时,它会消失。它也不应该发生在现场环境中。我可能会向他们发送消息...
请在这里找到我的解决方案:Fiddle
window.smoothScroll = function(target) {
var scrollContainer = target;
do { //find scroll container
scrollContainer = scrollContainer.parentNode;
if (!scrollContainer) return;
scrollContainer.scrollTop += 1;
} while (scrollContainer.scrollTop == 0);
var targetY = -1* document.getElementsByClassName("navbar")[0].offsetHeight;;
console.log (document.getElementsByClassName("navbar")[0].height);
do { //find the top of target relatively to the container
if (target == scrollContainer) break;
targetY += target.offsetTop;
} while (target = target.offsetParent);
scroll = function(c, a, b, i) {
i = i+ 0.125; if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function(){ scroll(c, a, b, i); }, 50);
}
// start scrolling
scroll(scrollContainer, scrollContainer.scrollTop, targetY, 0);
}
我已经将 targetY 设置为:-1* document.getElementsByClassName("navbar")[0].offsetHeight;这已经解决了目标问题。至于平滑滚动,我将移动的增量减少为:0.125.
我找到了这个 javascript 平滑滚动的代码
window.smoothScroll = function(target) {
var scrollContainer = target;
do { //find scroll container
scrollContainer = scrollContainer.parentNode;
if (!scrollContainer) return;
scrollContainer.scrollTop += 1;
} while (scrollContainer.scrollTop == 0);
var targetY = 0;
do { //find the top of target relatively to the container
if (target == scrollContainer) break;
targetY += target.offsetTop;
} while (target = target.offsetParent);
scroll = function(c, a, b, i) {
i++; if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function(){ scroll(c, a, b, i); }, 20);
}
// start scrolling
scroll(scrollContainer, scrollContainer.scrollTop, targetY, 0);
}
并变得简单 example here。
如您所见,它正在滚动到红色部分,但不排除导航栏的高度。红色部分的开头一直到页面顶部,在导航栏下。
如何向该脚本添加偏移量,以便在点击导航栏时红色部分停止?填充不是一个选项,我已经尝试过了,但看起来不太好。我也需要这个在香草 javascript,而不是 jquery.
提前致谢!
看看这个,它计算 header 的高度,然后从滚动位置中减去它:
header = document.querySelectorAll('.navbar'),
space = header[0].clientHeight;
...
var targetY = -space;
更新 - 在评论中请求功能以重新定义偏移量。为此,我将 targetY
设为全局变量,它可以通过执行一个函数来取消更新。因此,在 class 在滚动时切换的脚本中,在那之后只需添加一行 headerSpace();
,它将重新计算高度。根据我的阅读,最初的 class 也仍然存在,因此它应该无需任何进一步调整即可工作。
按钮上的内联脚本也被删除并制作成事件侦听器...
最终版本 - requestAnimationFrame
的实施将使动画更流畅,在 CPU 上也更容易。当该功能不可用时,保留原始功能作为后备。可以使用顶部的变量设置持续时间(600 毫秒现在匹配之前设置的 20 毫秒的 30 个步骤)。还认为将 header 高度检查放在按钮单击事件处理程序中可能很方便。所以它总是在用户激活滚动动画时重新计算(并且不再需要将它直接挂接到切换 class 中):
duration = 600
基本代码:
scroll = function(c, a, b, i) {
if (modern) {
var present = Date.now(),
elapsed = present-initial,
progress = Math.min(elapsed/duration, 1);
c.scrollTop = a + (b - a) * progress;
if (progress < 1) requestAnimationFrame(function() {
scroll(c, a, b, i);
});
}
else {
i++; if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function() {scroll(c, a, b, i)}, 20);
}
}
作为旁注,第一次单击按钮时它可能看起来很突然,但这是因为 Codepen。我怀疑焦点在 window 上,其中包含脚本,而不是内容本身。因此 window 必须首先 'wake up',requestAnimationFrame
的节能方面。当首先单击内容内的其他任何地方时,它会消失。它也不应该发生在现场环境中。我可能会向他们发送消息...
请在这里找到我的解决方案:Fiddle
window.smoothScroll = function(target) {
var scrollContainer = target;
do { //find scroll container
scrollContainer = scrollContainer.parentNode;
if (!scrollContainer) return;
scrollContainer.scrollTop += 1;
} while (scrollContainer.scrollTop == 0);
var targetY = -1* document.getElementsByClassName("navbar")[0].offsetHeight;;
console.log (document.getElementsByClassName("navbar")[0].height);
do { //find the top of target relatively to the container
if (target == scrollContainer) break;
targetY += target.offsetTop;
} while (target = target.offsetParent);
scroll = function(c, a, b, i) {
i = i+ 0.125; if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function(){ scroll(c, a, b, i); }, 50);
}
// start scrolling
scroll(scrollContainer, scrollContainer.scrollTop, targetY, 0);
}
我已经将 targetY 设置为:-1* document.getElementsByClassName("navbar")[0].offsetHeight;这已经解决了目标问题。至于平滑滚动,我将移动的增量减少为:0.125.