单击时平滑滚动到特定div

时间:2013-08-06 02:48:43

标签: javascript jquery

我正在尝试做的是,如果你点击一个按钮,它会向下滚动(平滑)到页面上的特定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>

7 个答案:

答案 0 :(得分:146)

做的:

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

更新了Jsfiddle

答案 1 :(得分:28)

有很多使用jQuery,Mootools,Prototype等JS库进行平滑滚动的例子。

以下示例适用于纯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 Part:

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

答案 2 :(得分:8)

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

答案 3 :(得分:7)

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

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

也具有{行为:“平稳”} ....;)https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

答案 4 :(得分:2)

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

html {
  scroll-behavior: smooth;
}

答案 5 :(得分:1)

我采用了img的版本,并对其进行了调整以允许向上滚动。

2.800.000.000

答案 6 :(得分:1)

内德·罗克森(Ned Rockson)基本上回答了这个问题。但是,他的解决方案存在致命缺陷。当目标元素比视口高度更靠近页面底部时,该函数不会到达其退出语句,并且会将用户捕获在页面底部。只需限制迭代次数即可解决。

template <typename T>
concept is_mytype =
    std::is_same_v<
        std::remove_const_t<T>,
        mytype<decltype(T::a_inst), decltype(T::b_inst), decltype(T::c_inst)>>;