Project

General

Profile

1
import {NavigationEnd, Router} from '@angular/router';
2
import {Injectable} from '@angular/core';
3
import {Subscription} from 'rxjs';
4

    
5
@Injectable({
6
  providedIn: 'root'
7
})
8
export class SmoothScroll {
9
  private interval;
10
  private readonly sub;
11
  private lastRoute;
12

    
13
  constructor(private router: Router) {
14
    this.sub = router.events.subscribe(event => {
15
      if (event instanceof NavigationEnd) {
16
        if(this.interval) {
17
          clearInterval(this.interval);
18
        }
19
        const fragment = router.parseUrl(router.url).fragment;
20
        if (fragment) {
21
          let i = 0;
22
          this.interval = setInterval(() => {
23
            i++;
24
            const element = document.getElementById(fragment);
25
            if (element) {
26
              if(this.interval) {
27
                clearInterval(this.interval);
28
              }
29
              const yOffset = -100;
30
              let position = 0;
31
              let interval = setInterval(() => {
32
                if(position !== element.getBoundingClientRect().top) {
33
                  position = element.getBoundingClientRect().top;
34
                } else {
35
                  clearInterval(interval);
36
                  const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset;
37
                  window.scrollTo({top: y, behavior: 'smooth'});
38
                }
39
              }, 50);
40
            }
41
            if(i > 4 && this.interval) {
42
              clearInterval(this.interval);
43
            }
44
          }, 100);
45
        } else {
46
          if(this.lastRoute !== this.getUrl(event.url)) {
47
            window.scrollTo({top: 0});
48
          } else {
49
            window.scrollTo({top: 0, behavior: "smooth"});
50
          }
51
        }
52
        this.lastRoute = this.getUrl(event.url);
53
      }
54
    });
55
  }
56

    
57
  private getUrl(url: string) {
58
    return url.split('?')[0].split('#')[0];
59
  }
60

    
61
  public clearSubscriptions() {
62
    if(this.sub && this.sub instanceof Subscription) {
63
      this.sub.unsubscribe();
64
    }
65
    if(this.interval) {
66
      clearInterval(this.interval);
67
    }
68
  }
69
}
(4-4/4)