RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 676303
Accepted
Shperung
Shperung
Asked:2020-06-07 15:39:54 +0000 UTC2020-06-07 15:39:54 +0000 UTC 2020-06-07 15:39:54 +0000 UTC

无需 jQuery 即可平滑滚动到锚点

  • 772

有一个很棒的平滑滚动 jQuery 脚本。

var $page = $('html, body');
$('a[href*="#"]').click(function() {
    $page.animate({
        scrollTop: $($.attr(this, 'href')).offset().top
    }, 400);
    return false;
});

如何用纯 JS 渲染?

javascript
  • 6 6 个回答
  • 10 Views

6 个回答

  • Voted
  1. Sasha Omelchenko
    2020-09-05T17:04:09Z2020-09-05T17:04:09Z

    还有一个标准的平滑滚动方法Element.scrollIntoView()。

    const anchors = document.querySelectorAll('a[href*="#"]')
    
    for (let anchor of anchors) {
      anchor.addEventListener('click', function (e) {
        e.preventDefault()
        
        const blockID = anchor.getAttribute('href').substr(1)
        
        document.getElementById(blockID).scrollIntoView({
          behavior: 'smooth',
          block: 'start'
        })
      })
    }
    h2 {
      margin-bottom: 100vh;
    }
    <ul>
      <li><a href="#head1">head 1</a>
      <li><a href="#head2">head 2</a>
      <li><a href="#head3">head 3</a>
      <li><a href="#head4">head 4</a>
    </ul>
    
    <h2 id="head1">heading 1</h2>
    <h2 id="head2">heading 2</h2>
    <h2 id="head3">heading 3</h2>
    <h2 id="head4">heading 4</h2>

    • 26
  2. Best Answer
    Sasha Omelchenko
    2020-06-07T16:49:06Z2020-06-07T16:49:06Z

    // собираем все якоря; устанавливаем время анимации и количество кадров
    const anchors = [].slice.call(document.querySelectorAll('a[href*="#"]')),
          animationTime = 300,
          framesCount = 20;
    
    anchors.forEach(function(item) {
      // каждому якорю присваиваем обработчик события
      item.addEventListener('click', function(e) {
        // убираем стандартное поведение
        e.preventDefault();
        
        // для каждого якоря берем соответствующий ему элемент и определяем его координату Y
        let coordY = document.querySelector(item.getAttribute('href')).getBoundingClientRect().top + window.pageYOffset;
        
        // запускаем интервал, в котором
        let scroller = setInterval(function() {
          // считаем на сколько скроллить за 1 такт
          let scrollBy = coordY / framesCount;
          
          // если к-во пикселей для скролла за 1 такт больше расстояния до элемента
          // и дно страницы не достигнуто
          if(scrollBy > window.pageYOffset - coordY && window.innerHeight + window.pageYOffset < document.body.offsetHeight) {
            // то скроллим на к-во пикселей, которое соответствует одному такту
            window.scrollBy(0, scrollBy);
          } else {
            // иначе добираемся до элемента и выходим из интервала
            window.scrollTo(0, coordY);
            clearInterval(scroller);
          }
        // время интервала равняется частному от времени анимации и к-ва кадров
        }, animationTime / framesCount);
      });
    });
    h2 {
      margin-bottom: 100vh;
    }
    <ul>
      <li><a href="#head1">head 1</a>
      <li><a href="#head2">head 2</a>
      <li><a href="#head3">head 3</a>
      <li><a href="#head4">head 4</a>
    </ul>
    
    <h2 id="head1">heading 1</h2>
    <h2 id="head2">heading 2</h2>
    <h2 id="head3">heading 3</h2>
    <h2 id="head4">heading 4</h2>

    • 17
  3. Crantisz
    2020-06-07T15:52:35Z2020-06-07T15:52:35Z

    跨平台选项:

    currentYPosition- 确定滚动的当前位置

    elmYPosition- 确定元素的位置

    smoothScroll是函数本身。

    function currentYPosition() {
        // Firefox, Chrome, Opera, Safari
        if (self.pageYOffset) return self.pageYOffset;
        // Internet Explorer 6 - standards mode
        if (document.documentElement && document.documentElement.scrollTop)
            return document.documentElement.scrollTop;
        // Internet Explorer 6, 7 and 8
        if (document.body.scrollTop) return document.body.scrollTop;
        return 0;
    }
    
    
    function elmYPosition(eID) {
        var elm = document.getElementById(eID);
        var y = elm.offsetTop;
        var node = elm;
        while (node.offsetParent && node.offsetParent != document.body) {
            node = node.offsetParent;
            y += node.offsetTop;
        } return y;
    }
    
    
    function smoothScroll(eID) {
        var startY = currentYPosition();
        var stopY = elmYPosition(eID);
        var distance = stopY > startY ? stopY - startY : startY - stopY;
        if (distance < 100) {
            scrollTo(0, stopY); return;
        }
        var speed = Math.round(distance / 100);
        if (speed >= 20) speed = 20;
        var step = Math.round(distance / 25);
        var leapY = stopY > startY ? startY + step : startY - step;
        var timer = 0;
        if (stopY > startY) {
            for ( var i=startY; i<stopY; i+=step ) {
                setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
                leapY += step; if (leapY > stopY) leapY = stopY; timer++;
            } return;
        }
        for ( var i=startY; i>stopY; i-=step ) {
            setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
            leapY -= step; if (leapY < stopY) leapY = stopY; timer++;
        }
    }
    

    取自这里的答案

    当您只需要滚动到特定位置时的简化版本

    function scrollTo(element, to, duration) {
        if (duration <= 0) return;
        var difference = to - element.scrollTop;
        var perTick = difference / duration * 10;
    
        setTimeout(function() {
            element.scrollTop = element.scrollTop + perTick;
            if (element.scrollTop === to) return;
            scrollTo(element, to, duration - 10);
        }, 10);
    }
    

    取自这里的答案

    • 10
  4. user326576
    2020-02-11T21:56:33Z2020-02-11T21:56:33Z
    var nodeObj = document.querySelector('.button-node');
    
    nodeObj.scrollIntoView({
       behavior: "smooth",
       block:    "start" 
    });
    
    • 3
  5. Leone Marino
    2020-03-22T01:40:44Z2020-03-22T01:40:44Z
     const anim = (sel, duration) => {
      let to = document.querySelector(sel).getBoundingClientRect().top,
          temp;
    
      return (sel) => {
          cancelAnimationFrame(temp); 
          var start = performance.now(); 
          var from = window.pageYOffset || document.documentElement.scrollTop;        
          requestAnimationFrame(function step(timestamp) {
              var progress = (timestamp - start) / duration;
              1 <= progress && (progress = 1);
              window.scrollTo(0, from + to * progress | 0);  
              1 > progress && (temp = requestAnimationFrame(step))
          });
      }
    
    }
    
    • 1
  6. Евгений Колмак
    2022-07-08T03:35:54Z2022-07-08T03:35:54Z
    const scrollWindow = () => {
    // На сколько пикселей будет прокручиваться страница
        let scrolled;
        let timer;
    //  Через сколько действие будет повторяться
    
    //  Получаем еэлемент через ID
        document.getElementById(IDelemen).onclick = function(){
            scrolled = window.pageYOffset;
    // Определяем место положение скролла на странице
        
    // запуск функции    
            scrollToTop(); 
        }
    //  Сама функции
        function scrollToTop(){
    // Если положение скрола не вверху страницы
            if (scrolled > 0) {
    //Скролим вверх 
                window.scrollTo(0, scrolled);
    // Скроллим веерх (отнимаем кол-во пикселей от текущего значения) 
                scrolled = scrolled - 50; //100 - скорость прокрутки
                timer = setTimeout(scrollToTop, 200); //время повторения
    // Через какое время запустить повторную проверку
    // Повторение будет продолжаться, пока scrolled не станет - 0
            }
            else {
                clearTimeout(timer);
                window.scrollTo(0,0);
    //Останавливаем по достижению верха страницы
            }
        }
    }
    // Вызов функкции
    scrollWindow ();
    
    // Регулировать плавность (прокрутной и повторением)
    
    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5