Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using HTML anchor link #id in Angular 6

I am working with an Angular 6 project in which I have disabled/removed hash-location-strategy which removes # from URL.

due to this change the link having:

<li routerLinkActive="active">
   <a [routerLink]="['/settings']">Contact Settings</a>
   <ul class="child-link-sub">
      <li>
         <a href="#contactTypes">Contact Types</a>
      </li>
   </ul>
</li>

is no more working it just skips the current components URL and puts #contactTypes after localhost.

I found this github issue which should solve the issue using

<a [routerLink]="['/settings/']" fragment="contactTypes" >Contact Types</a>

which puts #contactTypes at the end of the URL but it doesn't scroll to the top of the browser.

Source: https://github.com/angular/angular/issues/6595

like image 299
Suresh Karia Avatar asked Jun 13 '18 11:06

Suresh Karia


4 Answers

Angular 6.1 comes with an option called anchorScrolling that lives in router module's ExtraOptions. As the anchorScrolling definition says:

Configures if the router should scroll to the element when the url has a fragment.

'disabled' -- does nothing (default).

'enabled' -- scrolls to the element. This option will be the default in the future.

Anchor scrolling does not happen on 'popstate'. Instead, we restore the position that we stored or scroll to the top.

You can use it like that:

const routerOptions: ExtraOptions = {
  useHash: false,
  anchorScrolling: 'enabled',
  // ...any other options you'd like to use
};

// then just import your RouterModule with these options

RouterModule.forRoot(MY_APP_ROUTES, routerOptions)
like image 164
Machado Avatar answered Sep 30 '22 12:09

Machado


I was looking for a similar solution and tried to use the ngx-scroll-to package and found that its not working in latest version of angular so decided to look into other option and found that we can use scrollIntoView

HTML code :

<button (click)="scrollToElement(target)"></button>
<div #target>Your target</div>

Ts code :

  scrollToElement($element): void {
    console.log($element);
    $element.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
  }
like image 43
Joel Joseph Avatar answered Sep 30 '22 10:09

Joel Joseph


For accessibility reasons I had to a link at the beginning of the document to provide direct access to the content to user using a screen reader, skipping that way parts of the page repeating from page to page.

As I needed the link to stay focusable (preferably keeping the href attribute), as I was actually outside the app-root or any component (still solution works inside a component), to do that I used simple good old fashion html and javascript :

<a href="./#content"
     onclick="event.preventDefault(); location.hash='content';"
     class="content-shortcut"
     title="Access page content directly"
     i18n-title
     aria-label="Access page content directly"
     i18n-label>Access page content directly</a>
  <style>
    .content-shortcut {
      position: absolute;
      opacity: 0;
      height: 0px;
      font-size: 1px;
    }

    .content-shortcut:focus,
    .content-shortcut:active {
      position: relative;
      opacity: 1;
      height: auto;
      font-size: 1em;
      display: block;
      color: black;
      background: white;
    }

  </style>
like image 6
svassr Avatar answered Sep 30 '22 10:09

svassr


This worked for me (I'm using Angular 12.1.3):

On the HTML template:

<a (click)="scrollTo('anchorId')">Scroll to another position</a>

Pass the id of the element you want to scroll to (without the hashtag symbol #) to the function.

Then, on Typescript, use .scrollIntoView to make the browser scroll to the position of that element.

scrollTo(element: any): void {
  (document.getElementById(element) as HTMLElement).scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
}
like image 5
bc100k Avatar answered Sep 30 '22 10:09

bc100k