top ngx bottom scroll typescript angular smooth-scrolling

ngx - infinite scroll angular 6



Desplazamiento liso angular2 (9)

Bien, después de rascarme un poco la cabeza, aquí hay una solución que parece estar funcionando bien.

Igual que antes, cuando hice clic, declaré mi ID condicional y un botón con la función scrollTo.

Ahora, solo hay dos archivos en la solución es un servicio que ayudará a devolver la ventana del documento y el componente de la plantilla. No se ha cambiado nada en el servicio de ventana desde el estado anterior, pero lo incluiré de nuevo por el bien de una buena respuesta.

window.service.ts: salude a https://gist.github.com/lokanx/cc022ee0b8999cd3b7f5 por ayudar con esta pieza

import {Injectable, Provider} from ''angular2/core''; import {window} from ''angular2/src/facade/browser''; import {unimplemented} from ''angular2/src/facade/exceptions''; function _window(): Window { return window } export abstract class WINDOW { get nativeWindow(): Window { return unimplemented(); } } class WindowRef_ extends WINDOW { constructor() { super(); } get nativeWindow(): Window { return _window(); } } export const WINDOW_PROVIDERS = [ new Provider(WINDOW, { useClass: WindowRef_ }), ];

app.component.ts

import { bootstrap } from ''angular2/platform/browser''; import { Component } from ''angular2/core''; import {WINDOW, WINDOW_PROVIDERS} from ''./window.service''; @Component({ selector: ''my-app'', templateUrl: ''app.tpl.html'', providers: [WINDOW_PROVIDERS] }) class AppComponent { win: Window; private offSet: number; constructor( private _win: WINDOW) { this.win = _win.nativeWindow; } title = ''Ultra Racing''; things = new Array(200); scrollTo(yPoint: number, duration: number) { setTimeout(() => { this.win.window.scrollTo(0, yPoint) }, duration); return; } smoothScroll(eID) { var startY = currentYPosition(); var stopY = elmYPosition(eID); var distance = stopY > startY ? stopY - startY : startY - stopY; if (distance < 100) { this.win.window.scrollTo(0, stopY); return; } var speed = Math.round(distance / 100); if (speed >= 20) speed = 20; var step = Math.round(distance / 100); var leapY = stopY > startY ? startY + step : startY - step; var timer = 0; if (stopY > startY) { for (var i = startY; i < stopY; i += step) { this.scrollTo(leapY, timer * speed); leapY += step; if (leapY > stopY) leapY = stopY; timer++; } return; } for (var i = startY; i > stopY; i -= step) { this.scrollTo(leapY, timer * speed); leapY -= step; if (leapY < stopY) leapY = stopY; timer++; } } } function currentYPosition() { // Firefox, Chrome, Opera, Safari if (self.pageYOffset) return self.pageYOffset; // Internet Explorer 6 - standards mode if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop; // Internet Explorer 6, 7 and 8 if (document.body.scrollTop) return document.body.scrollTop; return 0; } function elmYPosition(eID) { var elm = document.getElementById(eID); var y = elm.offsetTop; var node = elm; while (node.offsetParent && node.offsetParent != document.body) { node = node.offsetParent; y += node.offsetTop; } return y; } bootstrap(AppComponent)

Creé un plunk para mostrar este ejemplo trabajando: Plunk Example

Estoy teniendo problemas para que un servicio de desplazamiento suave funcione en angular 2. ¿Hay algún servicio para desplazamiento suave o desplazamiento de ancla simple que pueda funcionar hasta que el equipo angular 2 haga que funcione el equivalente de $ anchorScroll angular2?

Hasta ahora solo he intentado:

Configuración de * ngFor ID incremental de bucle en un div principal

[attr.id]="''point'' + i"

Llamando un scrollto en un botón con la identificación pasada

<button type="button" class="btn btn-lg btn-default " (click)="smoothScroll(''point''+i)"> Scroll to point </button>

Y en el componente asociado, estoy tratando de implementar una función de desplazamiento suave liso js

smoothScroll(eID) { var startY = currentYPosition(); var stopY = elmYPosition(eID); var distance = stopY > startY ? stopY - startY : startY - stopY; if (distance < 100) { scrollTo(0, stopY); return; } var speed = Math.round(distance / 100); if (speed >= 20) speed = 20; var step = Math.round(distance / 25); var leapY = stopY > startY ? startY + step : startY - step; var timer = 0; if (stopY > startY) { for (var i = startY; i < stopY; i += step) { setTimeout(this.win.scrollTo(0, leapY), timer * speed); leapY += step; if (leapY > stopY) leapY = stopY; timer++; } return; } for (var i = startY; i > stopY; i -= step) { setTimeout(this.win.scrollTo(0,leapY), timer * speed); leapY -= step; if (leapY < stopY) leapY = stopY; timer++; } } function currentYPosition() { // Firefox, Chrome, Opera, Safari if (self.pageYOffset) return self.pageYOffset; // Internet Explorer 6 - standards mode if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop; // Internet Explorer 6, 7 and 8 if (document.body.scrollTop) return document.body.scrollTop; return 0; } function elmYPosition(eID) { var elm = document.getElementById(eID); var y = elm.offsetTop; var node = elm; while (node.offsetParent && node.offsetParent != document.body) { node = node.offsetParent; y += node.offsetTop; } return y; }

También estoy tratando de dar acceso a la ventana para this._win.scrollTo que viene de un servicio de proveedor de ventanas

import {Injectable, Provider} from ''angular2/core''; import {window} from ''angular2/src/facade/browser''; import {unimplemented} from ''angular2/src/facade/exceptions''; function _window(): Window { return window } export abstract class WINDOW { get nativeWindow(): Window { return unimplemented(); } } class WindowRef_ extends WINDOW { constructor() { super(); } get nativeWindow(): Window { return _window(); } } export const WINDOW_PROVIDERS = [ new Provider(WINDOW, { useClass: WindowRef_ }), ];

** EDITAR --------------------- **

Cambié el this.win.scrollTo por this.win.window.scrollTo y ahora obtengo un efecto similar a angular1.x $ anchorscroll donde el scroll es rápido en lugar de una transición suave, pero el scroll no es suave y Estoy recibiendo el siguiente error de excepción.

ACTUALIZAR

Ya no recibo ese error después de descubrir que angular2 está haciendo el setTimeout un poco diferente, pero el desplazamiento es instantáneo y no es un desplazamiento suave.

Cambié

setTimeout(this.win.scrollTo(0, leapY), timer * speed);

a

setTimeout(() => this.win.scrollTo(0, leapY), timer * speed);


Gracias a la respuesta aceptada, pude implementar un suave "scroll to top". Desplazarse hacia la parte superior es incluso más fácil que desplazarse a un elemento de destino particular, ya que siempre estamos desplazándonos hacia la posición 0. Aquí está el código:

scrollTo(yPoint: number, duration: number) { setTimeout(() => { window.scrollTo(0, yPoint) }, duration); return; } smoothScrollToTop() { let startY = this.currentYPosition(); let stopY = 0; // window top let distance = stopY > startY ? stopY - startY : startY - stopY; if (distance < 100) { window.scrollTo(0, stopY); return; } let speed = Math.round(distance / 100); let step = speed; speed = Math.max(9, speed); //min 9 otherwise it won''t look smooth let leapY = stopY > startY ? startY + step : startY - step; let timer = 0; if (stopY > startY) { for (let i = startY; i < stopY; i += step) { // since setTimeout is asynchronous, the for-loop will will fire all scrolls // nearly simoultaniously. Therefore, we need to multiply the speed with // a counter which lets the scrolls start with a growing offset which lets the // setTimeout wait for a growing time till it scrolls there // that way, we prevent the window to scroll instantly to the target Yposition this.scrollTo(leapY, timer * speed); leapY += step; if (leapY > stopY) leapY = stopY; timer++; } return; } else { for (let i = startY; i > stopY; i -= step) { this.scrollTo(leapY, timer * speed); leapY -= step; if (leapY < stopY) leapY = stopY; timer++; } } } currentYPosition() { // Firefox, Chrome, Opera, Safari if (self.pageYOffset) return self.pageYOffset; // Internet Explorer 6 - standards mode if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop; // Internet Explorer 6, 7 and 8 if (document.body.scrollTop) return document.body.scrollTop; return 0; }

Si lo desea, puede hacer que su botón "Desplazarse hacia arriba" aparezca dinámicamente cuando el usuario se desplaza:

@HostListener(''window:scroll'', [''$event'']) onWindowScroll(event) { this.onScrollFadeInOutScrollToTopButton(); } shouldShowScrollToTop: boolean = false; onScrollFadeInOutScrollToTopButton() { this.shouldShowScrollToTop = (window.pageYOffset >= window.screen.height/2); }

Y el HTML para el botón de desplazamiento hacia arriba:

<div class="back-to-top"> <button *ngIf="shouldShowScrollToTop" [@fadeInOutTrigger]="animateButtonEntryState" class="mat-primary" md-fab (click)="smoothScrollToTop()">^</button>

Como puedes ver, ese botón también tiene un disparador de animación. Puedes pensar en usar un ícono para el botón y, idealmente, tu botón debería tener una position:fixed; estilo.


Hay otro enfoque, que debería considerarse: usar jQuery.

Tal vez no sea tan elegante como las soluciones nativas, pero es muy fácil y funciona perfectamente.

En tu index.html debes agregar esto al final del cuerpo:

<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> <script> $(document).on("click", "a[href*=''#'']:not([href=''#''])", function() { if (location.pathname.replace(/^///,'''') == this.pathname.replace(/^///,'''') && location.hostname == this.hostname) { var target = $(this.hash); target = target.length ? target : $(''[name='' + this.hash.slice(1) +'']''); if (target.length) { $(''html, body'').animate({ scrollTop: target.offset().top - 100 }, 1000); return false; } } }); </script>

Y ahora puede utilizar la sencilla navegación <a href("#section")> esta manera:

<a href="#section2">Link</a>

También funciona con enrutamiento:

<a class="btn" role="button" routerLink="/contact" fragment="contact_form">Contact us!</a>


La forma más fácil de lograr esto es mediante el uso de este polyfill: http://iamdustan.com/smoothscroll/

  1. Instálelo como: npm install smoothscroll-polyfill
  2. Importa en tu archivo polyfill.ts como: require (''smoothscroll-polyfill''). Polyfill ();
  3. Ahora puedes usar la opción de comportamiento de scrollIntoView como:

    (document.querySelector (''#'' + anchor)). scrollIntoView ({behavior: ''smooth''});


Para cualquier persona que todavía esté en la búsqueda de un desplazamiento suave, la respuesta de @ alex-j funciona muy bien para mí en Angular 2.0, pero tuve que cambiar el servicio de Windows a esto:

import { Injectable } from ''@angular/core''; function _window() : any { // return the global native browser window object return window; } @Injectable() export class WindowRef { get nativeWindow() : any { return _window(); } }

Todos los accesorios para este blog http://juristr.com/blog/2016/09/ng2-get-window-ref/ - ahora tengo un servicio de desplazamiento sin problemas que puedo llamar desde cualquier lugar :)


Si desea un salto de anclaje muy simple que funcione después del enrutamiento y dentro de las vistas enrutadas, también puede usar ng2-simple-page-scroll .

<a simplePageScroll href="#myanchor">Go there</a>

O justo después del enrutamiento:

<a simplePageScroll [routerLink]="[''Home'']" href="#myanchor">Go there</a>

Hace un simple salto instantáneo, pero funciona.


Yo uso este código.

var dis = distance ; var interval = setInterval(() => { this.document.body.scrollTop = dis; dis=dis-5 ; if (dis<10){ clearInterval(interval); } }, 5);


ejemplo:

function goToElement(elemId){ let element = window.getElementById(elemId); element.scrollIntoView({behavior: "smooth"}); }


hay un método en la window objeto llamado scrollTo() . Si configura el comportamiento como "suave", la página manejará el desplazamiento suave. ejemplo (desplácese hasta la parte superior de la página):

window.scrollTo({ left: 0, top: 0, behavior: ''smooth'' });

Y con ejemplo de reserva:

try { window.scrollTo({ left: 0, top: 0, behavior: ''smooth'' }); } catch (e) { window.scrollTo(0, 0); }