Angular2 Hashtag routing to Anchor doesnt move page
Solution 1
A workaround might be to write a function in your component that sets the location.hash to the id of the div you want to navigate to.
<a (click)="goTo('destination')">Go TO DIV</a>
<div id='destination'>
<h2>Destination</h2>
</div>
Then in your component:
goTo(location: string): void {
window.location.hash = location;
}
Solution 2
Here's a very simple solution that worked for me:
In the component, add this method:
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();
});
}
And in the view, the <a>
tag will look like this:
<a (click)="navigateTo('#destination')">Destination</a>
Solution 3
This workaround should do the trick
<div [routerLink]="[]" fragment="destination">
<a href="#destination">Go TO DIV</a>
</div>
Solution 4
After seeing all the solutions here, I decided to go with a small and simple directive. Here's what I ended up with:
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(); }
}
The idea was to create something flexible, that could be attached to any element on the page.
Usage:
<a appAnchorTo target="#my-link">My Insights</a>
<div appAnchorTo target="#my-other-link">My Customers</div>
And don't forget to declare the directive on one of your Modules:
@NgModule({
...,
declarations: [
...,
AnchorToDirective,
]
})
Solution 5
This worked for me:
First, prepare MyAppComponent
for automatic scrolling in 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 );
}
}
} );
}
}
}
Then, navigate to my-app-route
sending 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 } );
}
}
jipson
Updated on June 28, 2022Comments
-
jipson almost 2 years
So I used the following post to figure out how to add a fragment to the url.
Angular2 Routing with Hashtag to page anchor
And the fragment gets added fine, however the page doesn't move to the resulting anchor. I have tried using both the
name
andid
attribute on the destinationdiv
, but neither seem to work.I'm using Angular Version 2.0.0-rc.3, and router version 3.0.0-alpha.6.
Thanks!
<a [routerLink]="[]" fragment="destination">Go TO DIV</a> <div id='destination'> <h2>Destination</h2> </div>
There is enough space between the 2 elements to tell if the page actually moves.
And as said before, the url correctly adds
#destination
to itself. -
Samurai Girl about 7 yearsI would add one note to this. It sets hash only once, so if the hash is already included in the page and you click on the same anchor link, it won't scroll to the destination. But it works if you clear the hash before setting ->
window.location.hash = ''; window.location.hash = location;
-
JonathanPeel about 7 yearsI tried this, it works, but then everything above the target disappears.
-
Mindsect Team over 6 yearsCurrently using Angular 4 / CLI. This was the BEST solution. Thank you! Also, simplest with smallest amount of code that actually worked.
-
Oliver over 6 yearsThanks, no TypeScript/JavaScript needed!. This stuff shouldn't be so hard. Feel like the wheel's being reinvented sometimes.
-
Gilles over 6 yearsFar less complicated than using the router. I understand why this is complicated because of routing and all that SPA stuff, but anchor links are such a basic feature.
-
Daniel Kucal over 6 yearsIt will not generate proper url on any path different than root.