web-dev-qa-db-fra.com

Angular 4 - Défilement pour ancrer

J'essaie de faire un simple défilement vers un élément d'ancrage sur la même page. En gros, la personne clique sur un bouton "Try It" et le défile vers une zone plus basse sur la page avec l'identifiant "login". Actuellement, il fonctionne avec un id="login" & <a href="#login"></a> de base, mais il saute à cette section. Idéalement, j'aimerais qu'il défile ici. Si j'utilise Angular4, existe-t-il un moyen de le faire ou quel est le moyen le plus simple? Merci!

Modèle entier ... (composant encore vide)

<div id="image-header">
    <div id="intro">
        <h1 class="text-center">Welcome to ThinkPlan</h1>
        <h3 class="text-center">Planning your way</h3>
        <a class="btn btn-outline-primary" href="#login" id="view">Try It</a> <!-- Where the user clicks to scroll -->
    </div>
</div>
<div class="container" id="info">
    <div class="row">
        <div class="col-md-12">
             <div class="space" id="login"></div> <!-- The place to scroll to -->
                <h1 class="text-center">ThinkPlan</h1>
                <form  class="form-horizontal">
                    <fieldset>
                        <legend>Login</legend>
                        <div class="form-group">
                            <label for="inputEmail" class="col-lg-2 control-label">Email</label>
                            <div class="col-lg-10">
                                <input type="text" class="form-control" id="inputEmail" placeholder="Email">
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="inputPassword" class="col-lg-2 control-label">Password</label>
                            <div class="col-lg-10">
                                <input type="password" class="form-control" id="inputPassword" placeholder="Password"> 
                            </div>
                        </div>
                        <div class="form-group" id="log-btn">
                            <div class="col-lg-10 col-lg-offset-2">
                                <button routerLink="/plan" type="submit" class="btn btn-outline-primary">Login</button>
                            </div>
                        </div>
                        <p class="lead text-center">New here? <a routerLink="signup">Sign up.</a></p>
                    </fieldset>
                </form>
        </div>
    </div>
</div>
9
lnamba

Je pense que c'est une solution plus simple:

Dans votre HTML: 

<a [routerLink]="['/']" fragment="login"></a>

Dans votre TypeScript:

ngOnInit() {
 this.route.fragment.subscribe(fragment => { this.fragment = fragment; });
}

ngAfterViewChecked(): void {
  try {
      if(this.fragment) {
          document.querySelector('#' + this.fragment).scrollIntoView();
      }
  } catch (e) { }
}
8
Sarah Dubois

Depuis Angular v6, il existe la nouvelle option anchorScrolling pour la RouterModule. Vous pouvez le définir dans l'importation du module:

imports: [
  ...,
  RouterModule.forRoot(routes, {anchorScrolling: 'enabled'})

Avec cela, Angular fera automatiquement défiler jusqu'à l'élément avec l'identifiant du fragment donné.

Cependant, cela ne fonctionne pas lorsque les données sont chargées de façon asynchrone, voir ceci problème Github .

Le défilement régulier n’est pas encore possible avec la variable RouterModule, mais vous pouvez le faire manuellement: 

targetElement.scrollIntoView({behavior: "smooth"})
4
Kim Kern

Avec Angular 4, vous pouvez avoir des problèmes d’ancrage à la même page.

J'ai résolu en utilisant cette façon

ng2-page-scroll

installer

npm install ng2-page-scroll --save

importer dans votre app.module.ts

import {Ng2PageScrollModule} from 'ng2-page-scroll';

@NgModule({
    imports: [
        /* Other imports here */
        Ng2PageScrollModule
        ]
})
export class AppModule {
}

testez-le dans votre composant html

<a pageScroll href="#test">Testing</a>
<div id="test">
2

AfterViewCheck() sera appelé à chaque fois que la ChangeDetection est déclenchée, c'est donc une mauvaise solution.

Utilisez AfterViewInit() comme

public ngAfterViewInit(): void {
  this.subscription = this.route.fragment
    .subscribe(fragment => {
        const targetElement = this.document.querySelector('#' + fragment);
        if (fragment && targetElement) {
            targetElement.scrollIntoView();
        } else {
            window.scrollTo(0, 0);
        }
    });
}
public ngOnDestroy(): void {
    this.subscription.unsubscribe();
}
0
Sergey Andreev