web-dev-qa-db-fra.com

Angular2 Hashtag routant vers Anchor ne déplace pas la page

J'ai donc utilisé le post suivant pour comprendre comment ajouter un fragment à l'URL.

Routage Angular2 avec hachage à l'ancre de la page

Et le fragment est bien ajouté, mais la page ne se déplace pas vers l'ancre obtenue. J'ai essayé d'utiliser les attributs name et id sur la destination div, mais ni l'un ni l'autre ne semblent fonctionner.

J'utilise Angular Version 2.0.0-rc.3 et la version de routeur 3.0.0-alpha.6.

Merci!

<a [routerLink]="[]" fragment="destination">Go TO DIV</a>

<div id='destination'>
    <h2>Destination</h2>
</div>

Il y a suffisamment d'espace entre les 2 éléments pour indiquer si la page est réellement déplacée.

Et comme dit précédemment, l’url ajoute correctement #destination à elle-même.

11
jipson

Une solution de contournement pourrait consister à écrire une fonction dans votre composant qui définisse location.hash sur l'id du div auquel vous souhaitez accéder.

<a (click)="goTo('destination')">Go TO DIV</a>

<div id='destination'>
    <h2>Destination</h2>
</div>

Puis dans votre composant:

goTo(location: string): void {
    window.location.hash = location;
}
14
JohnMAC

Cela a fonctionné pour moi:

Tout d’abord, préparez MyAppComponent pour le défilement automatique dans ngAfterViewChecked () ...

import { Component, OnInit, AfterViewChecked } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';

@Component( {
   [...]
} )
export class MyAppComponent implements OnInit, AfterViewChecked {

  private scrollExecuted: boolean = false;

  constructor( private activatedRoute: ActivatedRoute ) {}

  ngAfterViewChecked() {

    if ( !this.scrollExecuted ) {
      let routeFragmentSubscription: Subscription;

      // Automatic scroll
      routeFragmentSubscription =
        this.activatedRoute.fragment
          .subscribe( fragment => {
            if ( fragment ) {
              let element = document.getElementById( fragment );
              if ( element ) {
                element.scrollIntoView();

                this.scrollExecuted = true;

                // Free resources
                setTimeout(
                  () => {
                    console.log( 'routeFragmentSubscription unsubscribe' );
                    routeFragmentSubscription.unsubscribe();
                }, 1000 );
              }
            }
          } );
    }

  }

}

Ensuite, accédez à my-app-route envoi de prodID hashtag

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component( {
   [...]
} )
export class MyOtherComponent {

  constructor( private router: Router ) {}

  gotoHashtag( prodID: string ) {
    this.router.navigate( [ '/my-app-route' ], { fragment: prodID } );
  }

}
2
JavierFuentes

Après avoir vu toutes les solutions ici, j'ai décidé de suivre une directive simple et petite. Voici ce que j'ai fini avec:

import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({ selector: '[appAnchorTo]' })
export class AnchorToDirective {
  @Input() target: string;

  constructor(el: ElementRef) { el.nativeElement.style.cursor = 'pointer'; }

  @HostListener('click', ['$event'])
  onClick() { document.querySelector(this.target).scrollIntoView(); }
}

L'idée était de créer quelque chose de flexible pouvant être attaché à n'importe quel élément de la page.

Usage:

<a appAnchorTo target="#my-link">My Insights</a>
<div appAnchorTo target="#my-other-link">My Customers</div>

Et n'oubliez pas de déclarer la directive sur l'un de vos modules:

@NgModule({
    ...,
    declarations: [
        ...,
        AnchorToDirective,
    ]
})
2
rafaelbiten

Cette solution de contournement devrait faire l'affaire

<div [routerLink]="[]" fragment="destination">
  <a href="#destination">Go TO DIV</a>
</div>
2
Martin Cremer

Voici une solution très simple qui a fonctionné pour moi:

Dans le composant, ajoutez cette méthode:

navigateTo(location: string): void {
// location will be a valid CSS ID selector; i.e. it should be preceded with '#'
window.location.hash = location;
setTimeout(() => {
    document.querySelector(location).parentElement.scrollIntoView();
  });
}

Et dans la vue, la balise <a> ressemblera à ceci:

<a (click)="navigateTo('#destination')">Destination</a>
2
Soma Mbadiwe

Vous pouvez également utiliser ce plugin https://www.npmjs.com/package/ng2-page-scroll Il effectue un défilement animé vers une ancre donnée.

1
Well-Made

J'ai trouvé un plugin très utile disponible dans nmp - ngx-scroll-to , qui fonctionne très bien pour moi. Cependant, il est conçu pour Angular 4+, mais peut-être que quelqu'un trouvera cette réponse utile.

0
mpro