AngularJS-$ anchorScroll smooth / duration


115

AngularJS 문서를 읽고 $anchorScroll요소로 부드럽게 스크롤 할 수있는 기간 / 완화 옵션을 사용할 수 있는지 파악하지 못했습니다 .

단지 다음과 같이 말합니다.

$location.hash('bottom');

// call $anchorScroll()
$anchorScroll();

나는 jquery를 사용하지 않으며 원하지 않습니다. $anchorScroll스크롤을 더 부드럽게 만들기 위해 만들거나 확장하는 영리하지만 간단한 방법이 있습니까?

답변:


155

안타깝게도 $anchorScroll. 당신이 발견 한대로 $anchorScroll옵션이 없으며 $ngAnimate. 스크롤에 애니메이션을 적용하려면 자체 서비스 / 공장 또는 단순한 자바 스크립트를 사용해야합니다.

자가 학습을 위해 부드러운 스크롤 서비스로 예제를 모았습니다. 이 작업을 수행하는 더 좋은 방법이 있으므로 피드백이 권장됩니다.

요소로 스크롤하려면 요소에를 첨부합니다 ng-click="gotoElement(ID)". 나는 이것을 지시로 만드는 것이 더 나은 길이라고 생각합니다.

다음 은 jsFiddle작업 예제입니다 .

최신 정보

이제이를 수행하기위한 여러 타사 지침이 있습니다.


11
아주 좋아. 여기에 지침이 있습니다. gist.github.com/justinmc/d72f38339e0c654437a2
Justin McCandless

@JustinMcCandless 어떻게 당신의 지시를 부르나요? 시도해 보았습니다 : <a ng-click="anchor-smooth-school('about');"> 약 1 </a> <a ng-click="anchorSmoothScroll('about');"> 약 2 < / a>
Dan

1
단지 할 @Dan<a anchor-smooth-scroll>About 1</a> <a anchor-smooth-scroll>About 2</a>
저스틴 McCandless에게

1
좋아요,이 답변이 마음에 듭니다. 그러나 이것은 여전히 ​​AngularJS를 싫어하는 또 다른 이유를 추가합니다. 제 말은 JQuery scrollTo와 비교하여 이것의 크기를보세요
Felype

1
지시문을 사용하려면 ID (예 :)로 요소를 <div id="my-div">my div</div>만든 다음 다음과 같은 링크를 만듭니다 <a anchor-smooth-scroll="my-div">visit my div</a>..
Jason Swett

20

angular-scroll, 링크 " https://github.com/durated/angular-scroll/ "을 사용할 수도 있습니다 . 부드러운 스크롤링이며 전문적인 모습을 얻기 위해 약간의 여유 기능도 있습니다.


1
이 플러그인은 $ documents 이외의 다른 요소에서 작동합니까? 내가보기에 그 안에 행을 스크롤 할 수 있도록 사업부에 scrollToElement을 적용했는데, 그것은 작동하지 않았다 ..
Shaunak

10

Brett의 답변은 저에게 큰 도움이되었습니다. 모듈화와 테스트 가능성 측면에서 그의 솔루션에 약간의 변경을가했습니다.

다음은 테스트가 포함 된 다른 버전을 포함하는 JsFiddle의 또 다른 작업 예제입니다 .

테스트를 위해 Karma와 Jasmine을 사용하고 있습니다. 서명이 다음과 같이 약간 수정되었습니다.

 anchorSmoothScroll.scrollTo(elementId, speed);

여기서 element는 스크롤 할 필수 속성이고 speed는 선택 사항이며 기본값은 20입니다 (이전과 동일).



2

여기에있는 솔루션 중 어느 것도 실제로 OP가 원래 요청한 작업을 수행하지 않습니다. 즉, $anchorScroll스크롤을 부드럽게 만듭니다. 부드러운 스크롤링 지시문의 차이점은 $anchroScroll사용 / 수정한다는 점입니다 $location.hash(). 이는 경우에 따라 바람직 할 수 있습니다.

다음은 $ anchorScroll 스크롤링을 부드러운 스크롤링으로 대체하는 간단한 모듈의 요점입니다. 스크롤 자체를 위해 https://github.com/oblador/angular-scroll 라이브러리를 사용 합니다 (원하는 경우 다른 것으로 교체하면 쉬울 것입니다).

https://gist.github.com/mdvorak/fc8b531d3e082f3fdaa9
참고 : 실제로 $ anchorScroll이 원활하게 스크롤되지는 않지만 스크롤 처리기를 대체합니다.

mdvorakSmoothScroll애플리케이션에서 모듈 을 참조하여 간단히 활성화하십시오 .


0

앨런, 감사합니다. 관심있는 사람이 있다면 John Pappa 표준에 따라 형식을 지정했습니다.

(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

애니메이션 방법을 모릅니다 $anchorScroll. 내 프로젝트에서 수행하는 방법은 다음과 같습니다.

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

그리고 JS 기능 :

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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.