Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 8 scroll to a fragment, doesn't bring the fragment to the top of the page

I have a link, by clicking on the link, I want to scroll to a fragment which is at the bottom of the page. When I click on the link, the fragment is working, but it doesn't bring it to the top of the page.

I tried having the using div and section with an id to create the fragment. But, it doesn't bring the div or section to the top of the page.

The code in my app routing module is:

 imports: [
    RouterModule.forRoot(routes, {
    //useHash: true,
    scrollPositionRestoration: 'enabled',
    onSameUrlNavigation: 'reload',
    anchorScrolling: 'enabled'
  })]

My component code for link and fragment:

<a [routerLink]="['/proposal']" fragment="dcn">{{ dcn }}</a>

<section id="dcn">
Some other html here
</section>

Note, I have tried using useHash:true, but it doesn't seem to work. I would prefer a solution without useHash to be true.

like image 446
Nitin Avula Avatar asked Sep 16 '19 17:09

Nitin Avula


3 Answers

I use code like this to scroll to element:

HTML:

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

TS:

scroll(el: HTMLElement) {
    el.scrollIntoView();
}

Maybe this helps you.

Remember: to page scroll to element, page must have sufficient contents do generate a scroll/scrollbar, otherwise does not have content to scroll.

like image 129
Leonardo Getulio Avatar answered Nov 15 '22 03:11

Leonardo Getulio


I had the same situation and here is what I done:

This is the link on my menu component:

<a class="dropdown-item" routerLink="/products" fragment="product-one">Product One</a>

And this is how it is declared on my Product component... product.component.html

  <div class="anchor">
    <a name="product-one"></a>
    <h2 >Product One</h2><br>
  </div>

product.component.css

.anchor a {
    position: absolute;
    left: 0px;
    top: -10em;
  }
.anchor {
    position: relative;
  }

product.component.ts:

  //TODO: Needs to verify if is necessary to declare Router and ActivatedRoute
  constructor( router: Router,
    private route:ActivatedRoute,) {
   }

Have in count that the top attribute of CSS is equivalent of size of menu. On this way, when the scroll happens, it should display the anchored element just below the menu div.

I hope it helps...

like image 44
EHoltz Avatar answered Nov 15 '22 03:11

EHoltz


I have resolved this issue by implementing custom scroll restoration behavior.

The reason of this behavior is that page didn't already render and scrollToPosition no have effect.

There are not a good hack with timeout but it works.

export class AppModule {
  constructor(router: Router, viewportScroller: ViewportScroller) {
    router.events.pipe(
      filter((e): e is Scroll => e instanceof Scroll)
    ).subscribe(e => {
      if (e.position) {
        // backward navigation
        setTimeout(() => {viewportScroller.scrollToPosition(e.position); }, 0);
      } else if (e.anchor) {
        // anchor navigation
        setTimeout(() => {viewportScroller.scrollToAnchor(e.anchor); }, 0);
      } else {
        // forward navigation
        setTimeout(() => {viewportScroller.scrollToPosition([0, 0]); }, 0);
      }
    });
  }
}
like image 29
Roman Leliuk Avatar answered Nov 15 '22 03:11

Roman Leliuk