Smooth scroll anchor links WITHOUT jQuery

前端 未结 14 1922
暗喜
暗喜 2020-11-30 20:06

Is it possible to use smooth scroll to anchor links but without jQuery? I am creating a new site and I don\'t want to use jQuery.<

相关标签:
14条回答
  • 2020-11-30 20:51

    It's upgraded version from @Ian

    // Animated scroll with pure JS
    // duration constant in ms
    const animationDuration = 600;
    // scrollable layout
    const layout = document.querySelector('main');
    const fps = 12;  // in ms per scroll step, less value - smoother animation
    function scrollAnimate(elem, style, unit, from, to, time, prop) {
        if (!elem) {
            return;
        }
        var start = new Date().getTime(),
            timer = setInterval(function () {
                var step = Math.min(1, (new Date().getTime() - start) / time);
                var value =  (from + step * (to - from)) + unit;
                if (prop) {
                    elem[style] = value;
                } else {
                    elem.style[style] = value;
                }
                if (step === 1) {
                    clearInterval(timer);
                }
            }, fps);
        if (prop) {
            elem[style] = from + unit;
        } else {
            elem.style[style] = from + unit;
        }
    }
    
    function scrollTo(hash) {
        const target = document.getElementById(hash);
        const from = window.location.hash.substring(1) || 'start';
        const offsetFrom = document.getElementById(from).offsetTop;
        const offsetTo = target.offsetTop;
        scrollAnimate(layout,
            "scrollTop", "", offsetFrom, offsetTo, animationDuration, true);
        setTimeout(function () {
          window.location.hash = hash;
        }, animationDuration+25)
    };
    
    // add scroll when click on menu items 
    var menu_items = document.querySelectorAll('a.mdl-navigation__link');
    menu_items.forEach(function (elem) {
        elem.addEventListener("click",
            function (e) {
                e.preventDefault();
                scrollTo(elem.getAttribute('href').substring(1));
            });
    });
    
    // scroll when open link with anchor 
    window.onload = function () {
        if (window.location.hash) {
            var target = document.getElementById(window.location.hash.substring(1));
            scrollAnimate(layout, "scrollTop", "", 0, target.offsetTop, animationDuration, true);
        }
    }
    
    0 讨论(0)
  • 2020-11-30 20:52

    Try this code here:

    window.scrollTo({
            top: 0,
            left: 0,
            behavior: 'smooth'
        });
    
    0 讨论(0)
  • 2020-11-30 20:53

    This is a pretty old question, but I think it's important to say that nowadays smooth scrolling is supported in CSS, so there's no need for any scripts:

    html {
      scroll-behavior: smooth;
    }
    

    This property still has no support for Safari or IE/Edge as of 2019, so for a full crossbrowser support, you'll still have to use a script.

    0 讨论(0)
  • 2020-11-30 20:54

    My favorite scroll-to library currently is Zenscroll because of the wide range of features and small size (currently only 3.17kb).

    In the future it may make more sense to use the native scrollIntoView functionality, but since it'd have to be polyfilled in most production sites today due to the lack of IE support, I recommend using Zenscroll instead in all cases.

    0 讨论(0)
  • 2020-11-30 20:55

    Vanilla js variant using requestAnimationFrame with easings and all browsers supported:

    const requestAnimationFrame = window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame;
    
    function scrollTo(to) {
        const start = window.scrollY || window.pageYOffset
        const time = Date.now()
        const duration = Math.abs(start - to) / 3;
    
        (function step() {
            var dx = Math.min(1, (Date.now() - time) / duration)
            var pos = start + (to - start) * easeOutQuart(dx)
    
            window.scrollTo(0, pos)
    
            if (dx < 1) {
                requestAnimationFrame(step)
            }
        })()
    }
    

    Any easing supported!

    0 讨论(0)
  • 2020-11-30 20:57

    Based on MDN docs for scroll options we can use the following code:

    element.scrollTo({
      top: 100,
      left: 100,
      behavior: 'smooth'
    });
    

    In fact, the behavior key can accept smooth and auto variables. first for smooth motion and second for a single jump. ‍‍

    0 讨论(0)
提交回复
热议问题