单击时平滑滚动到特定 div

IT技术 javascript jquery
2021-03-11 23:23:13

我想要做的是,如果你点击一个按钮,它会向下(平滑地)滚动到页面上的特定 div。

我需要的是,如果您单击按钮,它会平滑滚动到 div 'second'。

.first {
    width: 100%;
    height: 1000px;
    background: #ccc;
}

.second {
    width: 100%;
    height: 1000px;
    background: #999;
}
<div class="first"><button type="button">Click Me!</button></div>
<div class="second">Hi</div>

6个回答

做:

$("button").click(function() {
    $('html,body').animate({
        scrollTop: $(".second").offset().top},
        'slow');
});

更新了Jsfiddle

你在这里使用的是 javaScript 还是 jQuery?
2021-04-20 23:23:13
@FahadUddin 它的 jQuery。
2021-05-04 23:23:13
@Sudhir Bastakoti 但许多用户抱怨滚动不顺畅。
2021-05-14 23:23:13
@SudhirBastakoti:为什么 JsFiddle 没有在该页面上包含它的 jquery 库?
2021-05-15 23:23:13

有很多使用 JS 库(如 jQuery、Mootools、Prototype 等)平滑滚动的示例。

以下示例基于纯 JavaScript。如果您在页面上没有 jQuery/Mootools/Prototype,或者您不想使用大量 JS 库重载页面,那么这个示例将有所帮助。

http://jsfiddle.net/rjSfP/

HTML部分:

<div class="first"><button type="button" onclick="smoothScroll(document.getElementById('second'))">Click Me!</button></div>
<div class="second" id="second">Hi</div>

CSS部分:

.first {
    width: 100%;
    height: 1000px;
    background: #ccc;
}

.second {
    width: 100%;
    height: 1000px;
    background: #999;
}

JS部分:

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);
}
5 年后仍然有用
2021-04-15 23:23:13
7 年 11 个月后仍然有帮助,添加了一个简单的属性
2021-04-16 23:23:13
知道如何在此代码中为固定导航栏添加偏移量吗?这是我制作小提琴的例子
2021-04-22 23:23:13
我正在使用它并且效果很好。我如何使滚动变慢?
2021-05-15 23:23:13

如果你使用 scrollIntoView 函数怎么办?

var elmntToView = document.getElementById("sectionId");
elmntToView.scrollIntoView(); 

也有 {behavior: "smooth"} .... ;) https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

我玩弄了 nico 的答案,感觉很紧张。做了一些调查,发现window.requestAnimationFrame哪个是在每个重绘周期调用的函数。这允许更干净的动画。仍然试图磨练步长的良好默认值,但对于我的示例,使用此实现看起来非常好。

var smoothScroll = function(elementId) {
    var MIN_PIXELS_PER_STEP = 16;
    var MAX_SCROLL_STEPS = 30;
    var target = document.getElementById(elementId);
    var scrollContainer = target;
    do {
        scrollContainer = scrollContainer.parentNode;
        if (!scrollContainer) return;
        scrollContainer.scrollTop += 1;
    } while (scrollContainer.scrollTop == 0);

    var targetY = 0;
    do {
        if (target == scrollContainer) break;
        targetY += target.offsetTop;
    } while (target = target.offsetParent);

    var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP,
                                 (targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);

    var stepFunc = function() {
        scrollContainer.scrollTop =
            Math.min(targetY, pixelsPerStep + scrollContainer.scrollTop);

        if (scrollContainer.scrollTop >= targetY) {
            return;
        }

        window.requestAnimationFrame(stepFunc);
    };

    window.requestAnimationFrame(stepFunc);
}
使用requestAnimationFrame代替setTimeout是要走的路。setTimeout不应该用于动画。
2021-04-16 23:23:13
@Alfonso 见上文。这只是之前答案中 nico 代码的优化版本。
2021-05-05 23:23:13
@KartikWatwani 这意味着在 reading 行上scrollContainer = scrollContainer.parentNode, scrollContainer 为空。这可能意味着您elementId在调用此函数时没有传递正确的信息您也可能在不存在该 elementId 的页面上运行此脚本。
2021-05-09 23:23:13
@NedRockson 对我不起作用给出控制台消息“未捕获的类型错误:无法读取 null 的属性‘parentNode’”但 nico 的代码正在运行,我应该怎么做才能应用干净的动画?
2021-05-11 23:23:13
@NedRockson 如果elementId我错了,我会在@nico 的例子中收到同样的错误,但在这种情况下滚动工作但不顺利。
2021-05-11 23:23:13

您可以使用基本的 css 来实现平滑滚动

html {
  scroll-behavior: smooth;
}