6

I have a menu bar with 4 tabs and when I press on every tab it should scroll down to the corresponding category (a specific id), on the same page. This is the code for the menu:

  template: `
        <div class="action-container">
          <div class="btn-group quick-navigation custom-group" role="group">
            <a *ngFor="let section of sections" [scrollTo]="section.id" (click)="active = section.id"
               class="btn btn-secondary" [class.active]="section.id == active">{{section.name}}</a>
          </div>
        </div>
      `,

And this one is the scroll directive:

 @Directive({
      selector: '[scrollTo]'
    })
    export class ScrollToDirective {
      @Input() scrollTo: string;
      @HostListener('click', ['$event']) onClick(e) {
        console.log(this.scrollTo);
        console.log($(`#${this.scrollTo}`).offset().top - 150);
        $('html, body').animate({
          scrollTop: $(`#${this.scrollTo}`).offset().top - 150
        }, 500);
      }
    }

The problem is that the offset().top-150 of a specific element changes after switching tabs multiple times and the first time it will redirect to the correct element, but after that, the page will jump randomly to different elements.

I have attached a print screen of the console.

console screenshot

Any suggestions? Thank you!

2 Answers 2

13

You don't have to compute any value to do what you want, and don't have to use JavaScript at all. At least, as you don't want a smooth scrolling.

You can easily scroll to any element with it id setting the href attribute :

<a href="#my_id" id="my_link">Click me to scroll down</a>

...

<section id="my_id">...</section>

Ok, according to your comment, there is a conflict with the angular's Router when doing this, so with a little bit of JavaScript you can solve the problem :

document.getElementById("my_link").addEventListener("click",(e)=>{
    e.preventDefault();
    document.querySelector(e.currentTarget.href).scrollIntoView();
});
Sign up to request clarification or add additional context in comments.

3 Comments

yes, I have tried this, but it conflicts with Angular's Router and instead of redirecting to the corresponding element, it will refresh the page.
Ok, so you can do the following in JavaScript : document.getElementById("my_id").scrollIntoView();
Thank you! It works! - document.getElementById(this.scrollTo).offsetTop - 150
11

Quick answer:

element = document.getElementById("message");
element.scrollIntoView();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.