AngularJS - $ anchorScroll yumuşak / süre


115

AngularJS belgelerini okuma $anchorScrollÖğeleri yumuşak kaydırmak için bir süre / hareket hızı seçeneğine sahip olup olamayacağımı anlayamadım .

Sadece şöyle diyor:

$location.hash('bottom');

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

Ben jquery kullanmıyorum ve istemiyorum; $anchorScrollKaydırmayı daha akıcı hale getirmek için yapmak veya genişletmek için hala akıllı ama basit bir yol var mı?

Yanıtlar:


155

Maalesef bunu kullanmak mümkün değil $anchorScroll. Keşfettiğin $anchorScrollgibi hiçbir seçeneğin yok ve çalışmıyor $ngAnimate. Kaydırmayı canlandırmak için kendi hizmetinizi / fabrikanızı veya sadece doğrudan javascript kullanmanız gerekir.

Kendi kendine öğrenme uğruna, sorunsuz bir kaydırma hizmetiyle bir örnek oluşturdum. Muhtemelen bunu yapmanın daha iyi yolları vardır, bu nedenle herhangi bir geri bildirim teşvik edilir.

Bir öğeye kaydırmak için ng-click="gotoElement(ID)"herhangi bir öğeye bir eklersiniz. Bence bunu bir direktif yapmak daha da iyi bir yol olacaktır.

İşte jsFiddle üzerinde çalışma örneği .

Güncelleme

Artık bunu başarmak için bir dizi üçüncü taraf yönergesi var.


11
Çok hoş. İşte bir yönerge olarak: gist.github.com/justinmc/d72f38339e0c654437a2
Justin McCandless

@JustinMcCandless yönergenizi nasıl çağırırsınız? Denedim: <a ng-click="anchor-smooth-school('about');"> Yaklaşık 1 </a> <a ng-click="anchorSmoothScroll('about');"> Yaklaşık 2 < / a>
Dan

1
@Dan just do<a anchor-smooth-scroll>About 1</a> <a anchor-smooth-scroll>About 2</a>
Justin McCandless

1
Güzel, bu cevabı beğendim. Ama yine de AngularJS'den nefret etmek için başka bir neden daha ekliyor, yani JQuery scrollTo
Felype

1
Yönergesini kullanmak için, kimliğine sahip bir öğe oluşturmak (örneğin <div id="my-div">my div</div>) ve daha sonra böyle bir bağlantı oluşturun: <a anchor-smooth-scroll="my-div">visit my div</a>.
Jason Swett

20

Ayrıca açısal kaydırma bağlantısını da kullanabilirsiniz, " https://github.com/durated/angular-scroll/ ". Profesyonel bir görünüm elde etmek için yumuşak kaydırma ve ayrıca birkaç hareket hızı işlevi vardır.


1
Bu eklenti $ belgeler dışında başka öğeler üzerinde çalışıyor mu? ScrollToElement öğesini bir div öğesine uygulamaya çalıştım, böylece içindeki bir satırı görünüme kaydırabilirim ve işe yaramadı ..
Shaunak

10

Brett'in cevabı benim için harika oldu. Modülerleştirme ve test edilebilirlik açısından çözümünde bazı küçük değişiklikler yaptım.

İşte JsFiddle üzerinde, testin de dahil olduğu diğer sürümü içeren başka bir çalışma örneği .

Test için Karma ve Jasmine kullanıyorum. İmza aşağıdaki gibi biraz değiştirildi:

 anchorSmoothScroll.scrollTo(elementId, speed);

Öğenin kaydırılması zorunlu bir öznitelik olduğu ve varsayılan değerin 20 olduğu yerlerde hız isteğe bağlıdır (daha önce olduğu gibi).



2

Buradaki çözümlerin hiçbiri aslında OP'nin sorduğu şeyi yapmıyor, yani $anchorScrollkaydırmayı sorunsuz bir şekilde yapmıyor . Düzgün kaydırma yönergeleri ile $anchroScrollkullanılması / değiştirmesi $location.hash()arasındaki fark, bazı durumlarda istenebilir.

Burada, $ anchorScroll kaydırmayı düzgün kaydırmayla değiştiren basit modülün özeti. Kaydırma işlemi için https://github.com/oblador/angular-scroll kitaplığını kullanır (isterseniz başka bir şeyle değiştirin, kolay olmalıdır).

https://gist.github.com/mdvorak/fc8b531d3e082f3fdaa9
Not: Aslında düzgün bir şekilde kaydırmak için $ anchorScroll almaz, ancak kaydırma için işleyicisinin yerini alır.

Basitçe mdvorakSmoothScrolluygulamanızda modülü referans alarak etkinleştirin .


0

Alan, teşekkür ederim. İlgilenen varsa, onu John Pappa standartlarına göre biçimlendirdim.

(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

Nasıl canlandırılacağının farkında değilim $anchorScroll. Projelerimde bunu şu şekilde yapıyorum:

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

Ve JS işlevi:

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.