AngularJS - $anchorScroll smooth/duration

后端 未结 7 1311
你的背包
你的背包 2020-12-04 07:52

Reading the AngularJS docs I haven\'t figured out if $anchorScroll can have a duration/easing option to smooth scroll to elements.

It only says:

相关标签:
7条回答
  • 2020-12-04 08:10

    None of the solutions here actually does what OP originally asked, that is, make $anchorScroll scrolling smoothly. Difference between smooth scrolling directives and $anchroScroll is that it uses/modifies $location.hash(), which may be desirable in some cases.

    Here is gist for simple module that replaces $anchorScroll scrolling with smooth scrolling. It uses https://github.com/oblador/angular-scroll library for the scrolling itself (replace it with something else if you want, it should be easy).

    https://gist.github.com/mdvorak/fc8b531d3e082f3fdaa9
    Note: It actually does not get $anchorScroll to scroll smoothly, but it replaces its handler for scrolling.

    Enable it simply by referencing mdvorakSmoothScroll module in your application.

    0 讨论(0)
  • 2020-12-04 08:11

    I am not aware of how to animate $anchorScroll . Here's how I do it in my projects:

    /* Scroll to top on each ui-router state change */
    $rootScope.$on('$stateChangeStart', function() {
     scrollToTop();
    });
    

    And the JS function:

    function scrollToTop() {
        if (typeof jQuery == 'undefined') {
            return window.scrollTo(0,0);
        } else {
            var body = $('html, body');
            body.animate({scrollTop:0}, '600', 'swing');
        }
        log("scrollToTop");
        return true;
    }
    
    0 讨论(0)
  • 2020-12-04 08:17

    Alan, thank you. If anyone interested, I formatted it based on John Pappa standards.

    (function() {
    
    'use strict';
    var moduleId = 'common';
    var serviceId = 'anchorSmoothScroll';
    
    angular
        .module(moduleId)
        .service(serviceId, anchorSmoothScroll);
    
    anchorSmoothScroll.$inject = ['$document', '$window'];
    
    function anchorSmoothScroll($document, $window) {
    
        var document = $document[0];
        var window = $window;
    
        var service = {
            scrollDown: scrollDown,
            scrollUp: scrollUp,
            scrollTo: scrollTo,
            scrollToTop: scrollToTop
        };
        return service;
    
        function getCurrentPagePosition(currentWindow, doc) {
            // Firefox, Chrome, Opera, Safari
            if (currentWindow.pageYOffset) return currentWindow.pageYOffset;
            // Internet Explorer 6 - standards mode
            if (doc.documentElement && doc.documentElement.scrollTop)
                return doc.documentElement.scrollTop;
            // Internet Explorer 6, 7 and 8
            if (doc.body.scrollTop) return doc.body.scrollTop;
            return 0;
        }
    
        function getElementY(doc, element) {
            var y = element.offsetTop;
            var node = element;
            while (node.offsetParent && node.offsetParent !== doc.body) {
                node = node.offsetParent;
                y += node.offsetTop;
            }
            return y;
        }
    
        function scrollDown(startY, stopY, speed, distance) {
    
            var timer = 0;
    
            var step = Math.round(distance / 25);
            var leapY = startY + step;
    
            for (var i = startY; i < stopY; i += step) {
                setTimeout('window.scrollTo(0, ' + leapY + ')', timer * speed);
                leapY += step;
                if (leapY > stopY) leapY = stopY;
                timer++;
            }
        };
    
        function scrollUp(startY, stopY, speed, distance) {
    
            var timer = 0;
    
            var step = Math.round(distance / 25);
            var leapY = startY - step;
    
            for (var i = startY; i > stopY; i -= step) {
                setTimeout('window.scrollTo(0, ' + leapY + ')', timer * speed);
                leapY -= step;
                if (leapY < stopY) leapY = stopY;
                timer++;
            }
        };
    
        function scrollToTop(stopY) {
            scrollTo(0, stopY);
        };
    
        function scrollTo(elementId, speed) {
    
            var element = document.getElementById(elementId);
    
            if (element) {
                var startY = getCurrentPagePosition(window, document);
                var stopY = getElementY(document, element);
    
                var distance = stopY > startY ? stopY - startY : startY - stopY;
    
                if (distance < 100) {
                    this.scrollToTop(stopY);
    
                } else {
    
                    var defaultSpeed = Math.round(distance / 100);
                    speed = speed || (defaultSpeed > 20 ? 20 : defaultSpeed);
    
                    if (stopY > startY) {
                        this.scrollDown(startY, stopY, speed, distance);
                    } else {
                        this.scrollUp(startY, stopY, speed, distance);
                    }
                }
    
            }
    
        };
    
    };
    
    })();
    
    0 讨论(0)
  • 2020-12-04 08:19

    You can also use the angular-scroll, link "https://github.com/durated/angular-scroll/". It is smooth scrolling also few easing functions to get a professional look.

    0 讨论(0)
  • 2020-12-04 08:23

    Unfortunately this is not possible using $anchorScroll. As you discovered $anchorScroll doesn't have any options and doesn't work with $ngAnimate. In order to animate the scroll you would need to use your own service/factory or just straight javascript.

    For the sake of self-learning I put together an example with a smooth scrolling service. There are probably better ways to do this so any feedback is encouraged.

    To scroll to an element you attach a ng-click="gotoElement(ID)" to any element. I think an even better route would be to make this a directive.

    Here's the working example on jsFiddle.

    Update

    There are now a number of third-party directives for accomplishing this.

    • https://github.com/oblador/angular-scroll.
    • https://github.com/d-oliveros/ngSmoothScroll
    • https://github.com/arnaudbreton/angular-smoothscroll
    • https://gist.github.com/justinmc/d72f38339e0c654437a2
    0 讨论(0)
  • 2020-12-04 08:24

    You can also use ngSmoothScroll, link: https://github.com/d-oliveros/ngSmoothScroll.

    Just include the smoothScroll module as a dependency and use it like this:

    <a href="#" scroll-to="my-element-3">Click me!</a>

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