Mike Poole
Mike Poole

Reputation: 2055

Angular 2 scrollIntoView Not Scrolling

I have a DIV with the id of footerWrapperTop in my HTML.

I have the following TypeScript in my component:

  ngAfterViewInit(): void {
    try {
      this.sFragment = 'footerWrapperTop';
      const nativeElement = document.querySelector('#' + this.sFragment);
      nativeElement.scrollIntoView();
    } catch (e) { }   }

However the page does not scroll down to the footer at runtime. What am I doing wrong?

If I console.dir(nativeElement); it shows the DIV in the console.

Upvotes: 2

Views: 6648

Answers (3)

San Jaisy
San Jaisy

Reputation: 17068

User Renderer2 from angular

import { Component, ElementRef, Renderer2, ViewChild } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <div #targetDiv style="height: 1000px;"></div>
    <button (click)="scrollToDiv()">Scroll to Div</button>
  `
})
export class AppComponent {
  @ViewChild('targetDiv') targetDiv: ElementRef;

  constructor(private renderer: Renderer2) {}

  scrollToDiv() {
    this.renderer.setProperty(window, 'scrollTo', {
      top: this.targetDiv.nativeElement.offsetTop,
      behavior: 'smooth'
    });
  }
}

Upvotes: 0

Kevin
Kevin

Reputation: 302

Please check this question: How to call scrollIntoView on an element in angular 2+

First add a template reference variable in the element (the #footerWrapperTop):

<div #footerWrapperTop></div>

in component.ts:

export class MyComponent {
  @ViewChild("footerWrapperTop") MyProp: ElementRef;

  ngAfterViewInit() {
    this.MyProp.nativeElement.scrollIntoView({ behavior: "smooth", block: "start" });
  }
}

However, when router changes, there is a bug in angular 5 and lower version. Angular 6 has fixed the problem. check this issue: https://github.com/angular/angular/issues/7791

Upvotes: 2

KShewengger
KShewengger

Reputation: 8269

You can use Angular's Renderer

Supply a Second Argument for selectRootElement as per Angular's Official Documentation as it is used to preserve your content

Syntax: selectRootElement(selectorOrNode: any, preserveContent?: boolean): any

Had created a Stackblitz Demo for your reference

import { Component, AfterViewInit, Renderer2 } from '@angular/core';


@Component({...})
export class ChildComponent implements AfterViewInit {

  sFragment: string;

  constructor(private renderer: Renderer2) {}

  ngAfterViewInit(): void {
      this.sFragment = 'footerWrapperTop';

      const element = this.renderer.selectRootElement(`#${this.sFragment}`, true); // true to indicate that you will preserve the content

      element.scrollIntoView({ behavior: 'smooth' });   // for smooth scrolling

  }

}

Upvotes: 7

Related Questions