繁体   English   中英

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);

}

并在这里做了简单的例子

如您所见,它滚动到红色部分,但不排除导航栏的高度。 红色部分的开始在导航栏下全部到达页面顶部。

如何为此脚本添加偏移量,以便红色部分在按下导航栏时停止? 填充不是一个选项,我已经尝试过,它看起来不太好。 另外我需要在vanila javascript中使用它,而不是jquery。

提前致谢!

看看这个,它会计算标题的高度,然后从滚动位置中减去它:

小提琴

header = document.querySelectorAll('.navbar'),
space = header[0].clientHeight;

...

var targetY = -space;

更新 - 评论中要求的功能,以重新定义偏移量。 为此我将targetY全局变量,可以通过执行函数来更新。 因此,在滚动的类切换的脚本中,在此之后只需添加一行headerSpace(); 它会重新计算高度。 根据我的阅读,初始课程仍然保持不变,无需进一步调整即可。

演示

按钮上的内联脚本也被删除并成为事件监听器...


最终版本 - requestAnimationFrame实现,它将使动画更加流畅,并且在CPU上也更容易。 当功能不可用时,原始功能将作为后备保留。 可以使用顶部的变量设置持续时间(600ms现在匹配之前设置的30ms的30步)。 还认为将标题高度检查放在按钮单击事件处理程序中可能很方便。 因此,当用户激活滚动动画时,它总是会重新计算(并且不再需要将其直接挂接到切换类中):

钢笔

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。 我怀疑焦点是在窗口中有脚本而不是内容本身。 因此,窗口必须首先“唤醒”,这是requestAnimationFrame节能方面。 当首先点击内容中的任何其他位置时,这将消失。 它也不应该在现场环境中发生。 我可能会给他们发一条关于它的消息......

请在这里找到我的解决方案: 小提琴

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);
}

我把putY放在:-1 * document.getElementsByClassName(“navbar”)[0] .offsetHeight; 这解决了目标问题。 至于顺利滚动,我已将动作的增量减少为:0.125。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM