jQuery 单击时平滑滚动到特定 div

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18071046/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 20:58:05  来源:igfitidea点击:

Smooth scroll to specific div on click

javascriptjquery

提问by Erik Fischer

What I'm trying to do is make it so that if you click on a button, it scrolls down (smoothly) to a specific div on the page.

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

What I need is if you click on the button, it smooth scrolls to the div 'second'.

我需要的是,如果您单击按钮,它会平滑滚动到 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>

回答by Sudhir Bastakoti

do:

做:

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

Updated Jsfiddle

更新了Jsfiddle

回答by nico

There are many examples of smooth scrolling using JS libraries like jQuery, Mootools, Prototype, etc.

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

The following example is on pure JavaScript. If you have no jQuery/Mootools/Prototype on page or you don't want to overload page with heavy JS libraries the example will be of help.

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

http://jsfiddle.net/rjSfP/

http://jsfiddle.net/rjSfP/

HTML Part:

HTML部分:

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

CSS Part:

CSS部分:

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

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

JS Part:

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

回答by Ned Rockson

I played around with nico's answer a little and it felt jumpy. Did a bit of investigation and found window.requestAnimationFramewhich is a function that is called on each repaint cycle. This allows for a more clean-looking animation. Still trying to hone in on good default values for step size but for my example things look pretty good using this implementation.

我玩弄了 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);
}

回答by Ionut B.

What if u use scrollIntoView function?

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

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

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

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

回答by Marek Lisy

I took the Ned Rockson's version and adjusted it to allow upwards scrolls as well.

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

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,
    Math.abs(targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);

  var isUp = targetY < scrollContainer.scrollTop;

  var stepFunc = function() {
    if (isUp) {
      scrollContainer.scrollTop = Math.max(targetY, scrollContainer.scrollTop - pixelsPerStep);
      if (scrollContainer.scrollTop <= targetY) {
        return;
      }
    } else {
        scrollContainer.scrollTop = Math.min(targetY, scrollContainer.scrollTop + pixelsPerStep);

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

    window.requestAnimationFrame(stepFunc);
  };

  window.requestAnimationFrame(stepFunc);
};