Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I navigate to an anchor in Angular 7

I've enable the anchorScrolling in routingModule and all the path but when i click on links nothing happened.

'nav-bar.component.html'

<div id="mySidenav" class="sidenav" #sidenav>
   <a href="javascript:void(0)" class="closeBtn" 
   (click)="closeNav()">&times;</a>
   <a routerLink="/hazyMinds" [fragment]="'HazyMinds'">HazyMinds</a>
   <a routerLink="/ourGames" [fragment]="'Games'">Our Games</a>
   <a routerLink="/contact" [fragment]="'Contact'">Contact</a>
</div>
<span id="openNavBtn"  (click)="openNav()" #openBtn>&#9776;</span>



'app.component.html'

<app-nav-bar></app-nav-bar>
<app-hazy-minds id="HazyMinds"></app-hazy-minds>
<app-games id="Games" ></app-games>
<app-contact id="Contact"></app-contact>
<router-outlet></router-outlet>



'app-routing.module.ts'

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';

import {ContactComponent} from './contact/contact.component';
import {GamesComponent} from './games/games.component';
import {HazyMindsComponent} from './hazy-minds/hazy-minds.component';

const routes: Routes = [
  {path: '', redirectTo: '/', pathMatch: 'full'},
  {path: 'hazyMinds', component : HazyMindsComponent},
  {path: 'ourGames', component : GamesComponent},
  {path: 'contact', component : ContactComponent}
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      scrollPositionRestoration: 'enabled',
      anchorScrolling: 'enabled',
      scrollOffset: [0, 64]
    }),
    CommonModule
  ],
  exports: [
    RouterModule
  ]
})


export class AppRoutingModule { }

I expect that when i clicked on link it automatically scroll to the correct anchor.
Someone know what's wrong with my code? thanks

like image 954
samy ben Avatar asked Dec 19 '18 16:12

samy ben


People also ask

What is navigate () used for in Angular?

Angular provides extensive set of navigation feature to accommodate simple scenario to complex scenario. The process of defining navigation element and the corresponding view is called Routing. Angular provides a separate module, RouterModule to set up the navigation in the Angular application.

Can we use anchor tag in Angular?

Anchor tag has href and clicks event in legacy applications, but href are not supported in Angular application.

How to add anchor tag with click events in angular?

Anchor tag has href and clicks event in legacy applications, but href are not supported in Angular application. In the HTML template file, please add an anchor tag with click events as follows. Anchor displays as a link, change the style as cursor =pointer to clickable like a button

How to navigate imperatively in angular router?

There are two methods available on Angular’s Router class to navigate imperatively in your component classes: Router.navigate and Router.navigateByUrl. Both methods return a promise that resolve to true if the navigation is successful, null if there’s no navigation, false if the navigation fails or is completely rejected if there’s an error.

How to navigate from one page to another page in angular?

Using links, You can navigate from one page to another page or move from one position to another position on a single page. It achieves using the anchor href attribute in legacy javascript and jquery apps. In Angular application, the same can be achieved with the router link attribute as seen below. How to open link url in a new window in Angular?

Is href attribute required for navigation in angular?

href is not supported in Angular, But you can use a property binding event, for example, attach a click event to it, write a navigation code in click binding event. How do you navigate without the href attribute? You have to write a code to handle the anchor click binding event.


2 Answers

You can use fragments for this:

this.router.navigate(['/results'], { fragment: 'top' });

//

<h1 id="top">asdasd</h1>

https://angular.io/api/router/NavigationExtras

like image 150
enno.void Avatar answered Oct 16 '22 22:10

enno.void


So, I just spent like an hour on this with the latest Angular and other solutions worked OK for initial navigation but no matter what I tried, I could not get the anchor scrolling to work with navigation history.

In other words, when I went "back" or "forward" in my browser, the URL would update but I could not get Angular to scroll to the proper place. From logging, it seems that Angular was not actually acknowledging the fragment when going back/forward and so the scrolling was not being triggered.

I got fed up and decided to subscribe to the URL and manually scroll when a fragment is found, here's the code:

ngOnInit() {
  this.router.events.subscribe(val => {
    if (val instanceof NavigationEnd) {
      let fragmentIdx = val.urlAfterRedirects.lastIndexOf('#');
      if (fragmentIdx >= 0 && fragmentIdx < val.urlAfterRedirects.length - 1) {
        let fragment = val.urlAfterRedirects.substring(fragmentIdx+1);
        console.log('fragment: ' + fragment);
        document.getElementById(fragment).scrollIntoView();
      }
    }
  })
}

Just for clarity, you have to specify an id for the target element to scroll to.

Also, here's what my link looks like (for initial navigation):

<a routerLink="." fragment="anchor-name">Scroll To Anchor</a>

Now, I can visit different anchors and see the scrolling as I go back/forward in history. Hope it helps someone!

EDIT:

I have refactored this into its own service with a single method that I call from the ngOnInit of any page/component where I want anchor scrolling. I changed the settings in the main app module back to defaults as this is essentially doing things manually.

Here's the service:

import { Injectable } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AnchorScrollerService {

  constructor(private router: Router) { }

  listen() {
    this.router.events.subscribe(val => {
      // console.log(val);
      if (val instanceof NavigationEnd) {
        let fragmentIdx = val.urlAfterRedirects.lastIndexOf('#');
        if (fragmentIdx >= 0 && fragmentIdx < val.urlAfterRedirects.length - 1) {
          let fragment = val.urlAfterRedirects.substring(fragmentIdx+1);
          // console.log('fragment: ' + fragment);
          document.getElementById(fragment).scrollIntoView();
        }
      }
    })
  }
}

Now just call listen in your page's ngOnInit():

ngOnInit() {
  this.anchorScrollerService.listen();
}

Also, keep in mind that the latest Chrome has a bug with anchor scrolling that I'm seeing on initial navigation. Subsequent navigation/history works and all is perfect in, say, Firefox. Worth noting though in case you are having Chrome frustrations...you're not alone!

like image 3
GoForth Avatar answered Oct 16 '22 23:10

GoForth