首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在单页设计中突出显示导航栏中的当前部分

在单页设计中突出显示导航栏中的当前部分
EN

Stack Overflow用户
提问于 2021-10-04 08:05:06
回答 1查看 35关注 0票数 0

这是可行的,但当我按下链接时,滚动是令人难以置信的慢。是什么导致了这种情况?我怎么才能让滚动速度更快?我可以看到,人们已经问了几次这个问题,但所有的答案都是jquery。没有jquery也能做到吗?提前道谢

代码语言:javascript
复制
(function () {
    'use strict';
    var SectionScroller = {
        anchorTops: [],

        el: {
            anchors: document.querySelectorAll('.anchor'),
            anchorLinks: document.querySelectorAll('.anchor-link')
        },
        
        forEach: function(array, callback, scope) {
            for (var i = 0, ii = array.length; i < ii; i++) {
                callback.call(scope, i, array[i]);
            }
        },

        throttle: function (fn, threshhold, scope) {
          threshhold = threshhold || (threshhold = 250);
          var last;
          var deferTimer;
          return function () {
            var context = scope || this;
            var now = +new Date();
            var args = arguments;
            if (last && now < last + threshhold) {
              // hold on to it
              clearTimeout(deferTimer);
              deferTimer = setTimeout(function () {
                last = now;
                fn.apply(context, args);
              }, threshhold);
            } else {
              last = now;
              fn.apply(context, args);
            }
          };
        },
        
        mathSign: function (x) {
            x = +x; // convert to a number
            if (x === 0 || isNaN(x)) {
                return x;
            }
            return x > 0 ? 1 : -1;
        },

        anchorGetter: function () {
            var SS = SectionScroller;
            for (var i = 0, max = SS.el.anchors.length; i < max; i++) {
                SS.anchorTops[i] = SS.el.anchors[i].offsetTop;
            }
            for (var j = 0, jj = SS.anchorTops.length; j < jj; j++) {
                if (SS.anchorTops[j] - 1 < window.scrollY) {
                    for (var x = 0, xx = SS.el.anchors.length; x < xx; x++) {
                        SS.el.anchorLinks[x].classList.remove('selected');
                    }
                    SS.el.anchorLinks[j].classList.add('selected');
                }
            }
        },
        
        smooth: function (e) {
            var id = e.currentTarget.getAttribute('href');
            var node = document.querySelector(id);
            var nodeTop = node.offsetTop;
            var winTop = window.scrollY;
            var sign = SectionScroller.mathSign(nodeTop);
            var scrollAmnt;
            var down; 
            if (nodeTop > winTop) {
                down = true;
                scrollAmnt = nodeTop - winTop;
            } else {
                down = false;
                scrollAmnt = Math.abs(winTop - nodeTop);
            }
            
            var scroller = function () {
                if (down) {
                    window.scrollTo(0, window.scrollY + 1);
                } else {
                    window.scrollTo(0, window.scrollY - 1);
                }
                scrollAmnt--;
                if (scrollAmnt > 0)  {
                    window.requestAnimationFrame(scroller);
                }
            };
            window.requestAnimationFrame(scroller);
            e.preventDefault();
        },
        
        smoothScroll: function(e) {
            var id = e.currentTarget.getAttribute('href');
            var node = document.querySelector(id);
            var scrollContainer = node;
            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 (node == scrollContainer) break;
                targetY += node.offsetTop;
            } while (node === node.offsetParent);

            var 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);
            e.preventDefault();
        },

        events: function () {
            var SS = SectionScroller;
            window.addEventListener('scroll', SS.throttle(SS.anchorGetter, 150));
            SS.forEach(SS.el.anchorLinks, function (index, link) {
                link.addEventListener('click', SS.smooth);
            });
        },

        init: function () {
            SectionScroller.anchorGetter();
            SectionScroller.events();
        }
    };

    SectionScroller.init();
})();
代码语言:javascript
复制
* { box-sizing: border-box; }

section {
    display: block;
    height: 100vh;
    max-width: 100%;
    width: 100vw;
}



.selected { color: red; }

nav {
    position: fixed;
    right: 1em;
    top: 1em;
}

.anchor-link {
    display: block;
    margin-bottom: 1em;
    text-underline: none;
}
代码语言:javascript
复制
<nav>
    <a href="#anchor-1" class="anchor-link">Chapter 1</a>
    <a href="#anchor-2" class="anchor-link">Chapter 2</a>
    <a href="#anchor-3" class="anchor-link">Chapter 3</a>
    <a href="#anchor-4" class="anchor-link">Chapter 4</a>
    <a href="#anchor-5" class="anchor-link">Chapter 5</a>
</nav>

<section class="section">
    <a href="#" id="anchor-1" class="anchor">Chapter 1</a>
</section>
<section class="section">
    <a href="#" id="anchor-2" class="anchor">Chapter 2</a> 
</section>
<section class="section">
    <a href="#" id="anchor-3" class="anchor">Chapter 3</a>
</section>
<section class="section">
    <a href="#" id="anchor-4" class="anchor">Chapter 4</a>
</section>
<section class="section">
    <a href="#" id="anchor-5" class="anchor">Chapter 5</a>
</section>

这是可行的,但当我按下链接时,滚动是令人难以置信的慢。是什么导致了这种情况?我怎么才能让滚动速度更快?我可以看到,人们已经问了几次这个问题,但所有的答案都是jquery。没有jquery也能做到吗?感谢提前很多,这工作,但当我按链接滚动是难以置信的慢。是什么导致了这种情况?我怎么才能让滚动速度更快?我可以看到,人们已经问了几次这个问题,但所有的答案都是jquery。没有jquery也能做到吗?感谢提前很多,这工作,但当我按链接滚动是难以置信的慢。是什么导致了这种情况?我怎么才能让滚动速度更快?我可以看到,人们已经问了几次这个问题,但所有的答案都是jquery。没有jquery也能做到吗?提前道谢

EN

回答 1

Stack Overflow用户

发布于 2021-10-04 10:46:17

所以我找到了我的问题的解决方案。

代码语言:javascript
复制
(function() {
  'use strict';
  var SectionScroller = {
    anchorTops: [],

    el: {
      anchors: document.querySelectorAll('.anchor'),
      anchorLinks: document.querySelectorAll('.anchor-link')
    },

    forEach: function(array, callback, scope) {
      for (var i = 0, ii = array.length; i < ii; i++) {
        callback.call(scope, i, array[i]);
      }
    },

    throttle: function(fn, threshhold, scope) {
      threshhold = threshhold || (threshhold = 250);
      var last;
      var deferTimer;
      return function() {
        var context = scope || this;
        var now = +new Date();
        var args = arguments;
        if (last && now < last + threshhold) {
          // hold on to it
          clearTimeout(deferTimer);
          deferTimer = setTimeout(function() {
            last = now;
            fn.apply(context, args);
          }, threshhold);
        } else {
          last = now;
          fn.apply(context, args);
        }
      };
    },

    anchorGetter: function() {
      var SS = SectionScroller;
      for (var i = 0, max = SS.el.anchors.length; i < max; i++) {
        SS.anchorTops[i] = SS.el.anchors[i].offsetTop;
      }
      for (var j = 0, jj = SS.anchorTops.length; j < jj; j++) {
        if (SS.anchorTops[j] - 1 < window.scrollY) {
          for (var x = 0, xx = SS.el.anchors.length; x < xx; x++) {
            SS.el.anchorLinks[x].classList.remove('selected');
          }
          SS.el.anchorLinks[j].classList.add('selected');
        }
      }
    },


    smooth: function(e) {
      var id = e.currentTarget.getAttribute('link');
      document.getElementById(id).scrollIntoView({
        behavior: 'smooth'
      });
    },

    events: function() {
      var SS = SectionScroller;
      window.addEventListener('scroll', SS.throttle(SS.anchorGetter, 150));
      SS.forEach(SS.el.anchorLinks, function(index, link) {
        link.addEventListener('click', SS.smooth);
      });
    },

    init: function() {
      SectionScroller.anchorGetter();
      SectionScroller.events();
    }
  };

  SectionScroller.init();
})();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69432747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档