115

要素へのスクロールをスムーズにする期間/イージングオプションを使用できるかどうかはわかりませんでした。$anchorScroll

それは言うだけです:

$location.hash('bottom');

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

私はjqueryを使用していませんし、使用したくありません。$anchorScrollスクロールをよりスムーズにするために作成または拡張するための巧妙でシンプルな方法はまだありますか?

4

8 に答える 8

156

残念ながら、これは を使用して行うことはできません$anchorScroll。あなたが発見$anchorScrollしたように、オプションはなく、$ngAnimate. スクロールをアニメーション化するには、独自のサービス/ファクトリまたは単純な JavaScript を使用する必要があります。

自己学習のために、スムーズ スクロール サービスの例をまとめました。おそらくこれを行うためのより良い方法があるので、フィードバックをお寄せください。

要素にスクロールするには、ng-click="gotoElement(ID)"任意の要素に を付けます。これをディレクティブにするのがさらに良い方法だと思います。

jsFiddle の実際の例を次に示します。

アップデート

現在、これを実現するための多くのサードパーティ ディレクティブがあります。

于 2014-02-20T20:12:52.543 に答える
10

ブレットからの答えは私にとってうまくいきました。モジュール化とテスト容易性の観点から、彼のソリューションに小さな変更を加えました。

これは、テストを含む他のバージョンを含むJsFiddleのさらに別の作業例です。

テストのために、Karma と Jasmine を使用しています。署名は次のようにわずかに変更されました。

 anchorSmoothScroll.scrollTo(elementId, speed);

element はスクロール先の必須属性であり、 speed はオプションで、デフォルトは 20 です (以前と同様)。

于 2014-05-15T19:37:59.840 に答える
2

ngSmoothScroll を使用することもできます。リンク: https://github.com/d-oliveros/ngSmoothScroll

smoothScrollモジュールを依存関係として含めるだけで、次のように使用できます。

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

于 2015-03-10T00:47:01.237 に答える
2

$anchorScrollここでのソリューションはどれも、OPが最初に要求したこと、つまりスクロールをスムーズにすることを実際に行いません。スムーズ スクロール ディレクティブ と の違い$anchroScrollは、 を使用/変更する$location.hash()ことです。これは、場合によっては望ましい場合があります。

$anchorScroll スクロールをスムーズ スクロールに置き換えるシンプルなモジュールの要点を次に示します。スクロール自体にhttps://github.com/oblador/angular-scrollライブラリを使用します(必要に応じて別のものに置き換えてください。簡単なはずです)。

https://gist.github.com/mdvorak/fc8b531d3e082f3fdaa9
注: 実際には $anchorScroll をスムーズにスクロールすることはできませんが、スクロール用のハンドラーを置き換えます。

mdvorakSmoothScrollアプリケーションでモジュールを参照するだけで有効にできます。

于 2015-03-10T09:10:07.420 に答える
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);
                }
            }

        }

    };

};

})();
于 2016-05-06T15:51:36.803 に答える