top bottom anchorscroll javascript angularjs scroll anchor-scroll

javascript - bottom - angularjs scroll to top



AngularJS-$ anchorScroll suave/duraciĆ³n (7)

Lectura de los documentos de AngularJS No he descubierto si $anchorScroll puede tener una opción de duración / aceleración para suavizar el desplazamiento a los elementos.

Solo dice:

$location.hash(''bottom''); // call $anchorScroll() $anchorScroll();

No uso jquery y no quiero; ¿Existe todavía una manera inteligente pero simple de hacer o extender $anchorScroll para hacer el desplazamiento más suave?


Alan, gracias. Si alguien está interesado, lo formateé según los estándares de 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); } } } }; }; })();


Desafortunadamente esto no es posible usando $anchorScroll . Como descubriste, $anchorScroll no tiene ninguna opción y no funciona con $ngAnimate . Para animar el rollo, necesitaría usar su propio servicio / fábrica o simplemente javascript directo.

Por el bien del autoaprendizaje, armé un ejemplo con un servicio de desplazamiento suave. Probablemente haya mejores formas de hacerlo así que se recomienda cualquier comentario.

Para desplazarse a un elemento, adjunte un ng-click="gotoElement(ID)" a cualquier elemento. Creo que una ruta aún mejor sería hacer de esto una directiva.

Aquí está el ejemplo de trabajo en jsFiddle .

Actualizar

Ahora hay una serie de directivas de terceros para lograr esto.


La respuesta de Brett funcionó muy bien para mí. Hice algunos pequeños cambios en su solución en términos de modularización y capacidad de prueba.

Aquí hay otro ejemplo de trabajo en JsFiddle que incluye la otra versión con pruebas incluidas.

Para las pruebas, estoy usando Karma y Jasmine. La firma ha sido ligeramente modificada de la siguiente manera:

anchorSmoothScroll.scrollTo(elementId, speed);

Donde el elemento es un atributo obligatorio para desplazarse y la velocidad es opcional cuando el valor predeterminado es 20 (como era antes).


Ninguna de las soluciones aquí realmente hace lo que OP pidió originalmente, es decir, hace que $anchorScroll desplace suavemente. La diferencia entre las directivas de desplazamiento suave y $anchroScroll es que usa / modifica $location.hash() , lo que puede ser deseable en algunos casos.

Aquí está la esencia del módulo simple que reemplaza $ anchorScroll scrolling con desplazamiento suave. Utiliza la biblioteca https://github.com/oblador/angular-scroll para desplazarse por sí misma (reemplázala por otra cosa si quieres, debería ser fácil).

https://gist.github.com/mdvorak/fc8b531d3e082f3fdaa9
Nota: En realidad, no obtiene $ anchorScroll para desplazarse sin problemas, pero reemplaza su controlador para desplazarse.

Habilítelo simplemente haciendo referencia mdvorakSmoothScroll módulo mdvorakSmoothScroll en su aplicación.


No estoy al tanto de cómo animar $anchorScroll . Así es como lo hago en mis proyectos:

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

Y la función 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; }



También puede usar ngSmoothScroll, enlace: https://github.com/d-oliveros/ngSmoothScroll .

Simplemente incluya el módulo smoothScroll como una dependencia y utilícelo de esta manera:

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