【问题标题】:Smooth scroll to specific div on click单击时平滑滚动到特定的 div
【发布时间】:2013-08-06 02:48:43
【问题描述】:

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

【问题讨论】:

标签: javascript jquery


【解决方案1】:

做:

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

更新Jsfiddle

【讨论】:

  • 你这里用的是javaScript还是jQuery?
  • @FahadUddin 它的 jQuery。
  • @SudhirBastakoti:为什么 JsFiddle 没有在该页面上包含它的 jquery 库?
  • @Sudhir Bastakoti 但许多用户抱怨滚动不流畅。
【解决方案2】:

有很多使用 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部分:

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

【讨论】:

  • 我正在使用它,效果很好。我怎样才能让滚动变慢呢?
  • 知道如何在这段代码中为固定导航栏添加偏移量吗?这是我制作的示例fiddle
  • 5 年后仍然有用
  • 在 7 年 11 个月后仍然有帮助,添加了一个 ease 属性
  • 8 年 5 个月后仍然有用
【解决方案3】:

如果你使用 scrollIntoView 功能呢?

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

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • @Alfonso 见上文。这只是上一个答案中 nico 代码的优化版本。
    • @NedRockson 对我不起作用给控制台消息“Uncaught TypeError: Cannot read property 'parentNode' of null”但 nico 的代码正在工作,我应该怎么做才能应用干净的动画?跨度>
    • @KartikWatwani 这意味着在读取scrollContainer = scrollContainer.parentNode 的行上,scrollContainer 为空。这可能意味着您在调用此函数时没有传递正确的elementId。您也可能在该 elementId 不存在的页面上运行此脚本。
    • 使用requestAnimationFrame 而不是setTimeout 是要走的路。 setTimeout 不应该用于动画。
    【解决方案5】:

    对我有用的解决方案:

    var element = document.getElementById("box");
    
    element.scrollIntoView({behavior: "smooth"});
    

    您可以探索更多选项here

    【讨论】:

      【解决方案6】:

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

      html {
        scroll-behavior: smooth;
      }
      

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

          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,
                                           (targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);
          
              var iterations = 0;
              var stepFunc = function() {
                  if(iterations > MAX_SCROLL_STEPS){
                      return;
                  }
                  scrollContainer.scrollTop =
                      Math.min(targetY, pixelsPerStep + scrollContainer.scrollTop);
          
                  if (scrollContainer.scrollTop >= targetY) {
                      return;
                  }
          
                  window.requestAnimationFrame(stepFunc);
              };
          
              window.requestAnimationFrame(stepFunc);
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-12-16
            • 2014-05-14
            • 1970-01-01
            • 1970-01-01
            • 2021-12-25
            相关资源
            最近更新 更多