AngularJS - $ anchorScroll เรียบ / ระยะเวลา


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>
แดน

1
@Dan just do<a anchor-smooth-scroll>About 1</a> <a anchor-smooth-scroll>About 2</a>
Justin 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
ปลั๊กอินนี้ทำงานกับองค์ประกอบอื่น ๆ นอกเหนือจากเอกสาร $ หรือไม่ ฉันพยายามใช้ scrollToElement กับ div เพื่อให้ฉันสามารถเลื่อนแถวข้างในเข้าไปในมุมมอง แต่ก็ไม่ได้ผล ..
Shaunak

10

คำตอบจาก Brett เหมาะสำหรับฉัน ฉันได้ทำการเปลี่ยนแปลงเล็กน้อยในโซลูชันของเขาในแง่ของการแยกส่วนและการทดสอบ

นี่เป็นอีกหนึ่งตัวอย่างการทำงานบน JsFiddleที่มีเวอร์ชันอื่น ๆ พร้อมการทดสอบ

สำหรับการทดสอบฉันใช้ Karma และ Jasmine ลายเซ็นได้รับการแก้ไขเล็กน้อยดังนี้:

 anchorSmoothScroll.scrollTo(elementId, speed);

โดยที่องค์ประกอบเป็นแอตทริบิวต์ที่จำเป็นในการเลื่อนและความเร็วเป็นทางเลือกโดยที่ค่าเริ่มต้นคือ 20 (เหมือนเดิม)


2

นอกจากนี้คุณยังสามารถใช้ ngSmoothScroll เชื่อมโยง: https://github.com/d-oliveros/ngSmoothScroll

เพียงแค่รวมsmoothScrollโมดูลเป็นที่พึ่งพาและใช้มันดังนี้:

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


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.