滚动经过片段时,Angular 10会获得路由器活动片段吗?

Posted

技术标签:

【中文标题】滚动经过片段时,Angular 10会获得路由器活动片段吗?【英文标题】:Angular 10 get router active fragment when scrolling past the fragment? 【发布时间】:2020-11-09 12:55:40 【问题描述】:

我正在尝试在导航中突出显示您滚动过去的活动片段。

将片段和导航添加到片段很简单并且效果很好,例如:

      class="nav-button unselectable"
      matRipple
      routerLink="/"
      fragment="features"
      [ngClass]=" 'nav-active': (active_fragment | async) === 'features' "

但是路由器显然不知道你正在滚动哪个元素,所以我试图监听滚动事件并使用 Y 位置检查最近的元素。

但我的着陆页不是我导航的子页面,因此 viewchild 不起作用,例如:

导航组件:

  @ViewChild('features',  static: false )
  private _features: ElementRef;

  @HostListener('window:scroll', ['$event'])
  private _update_active_fragment(event: any) 
    event.preventDefault();

    console.log(window.pageYOffset);
    console.log(this._features.nativeElement);
  

着陆页组件:

  <app-features #features id="features"></app-features>

但是特性原生元素是未定义的。

我的问题是:

我还能如何实现此功能? 如何从导航组件中获取元素引用? 如何获取导航组件中 features 元素的 y 位置?

【问题讨论】:

嗨 Sebastian,您的导航和登录页面组件是同胞吗?你有他们两个共同的容器组件 - 比如 app.component.ts 左右?您在哪里有对 url 中的片段更改做出反应的逻辑?获得 y 位置后,您想如何继续? 你可以通过监听RouterOutlet指令的activate事件来获取激活组件:&lt;router-outlet (activate)="onActivate($event)"&gt;&lt;/router-outlet&gt;。我没试过,但我想你可以从那里得到 Y 坐标。 @MarcellKiss app.comp 包含 本身将显示 包含 片段。因此,我不能真正将它们都作为“共享”。 @ AndreiGătej 路由器插座本身不会监听滚动事件,也不会检查您正在滚动的片段。这只是在一定程度上。 可以肯定的是, 包含多个功能,因此您可以滚动浏览它们。而且您还有多个导航按钮,可以让您跳转到每个功能。这是一种方式(单击按钮并跳转到那里),但不是另一种方式(在滚动时激活按钮)。对吗? @MarcellKiss 正确 【参考方案1】:

做了一个新的导航服务:

public active_fragment: BehaviorSubject<string> = new BehaviorSubject('');

  constructor(private readonly route: ActivatedRoute) 
    this.route.fragment.subscribe((frag) => 
      this.active_fragment.next(frag);
    );
  

在我的导航组件中:

      [ngClass]="
        'nav-active': (navigationService.active_fragment | async) === 'home'
      "

在包含我的片段的登陆组件中:

  @ViewChild('features',  read: ElementRef )
  private _features: ElementRef;
  @ViewChild('benefits',  read: ElementRef )
  private _benefits: ElementRef;


  @HostListener('window:scroll', ['$event'])
  private _update_active_fragment(event: any) 
    event.preventDefault();
    switch (true) 
      case window.pageYOffset >=
        this._some_previous_element.nativeElement.offsetTop &&
        window.pageYOffset <= this._features.nativeElement.offsetTop: 
        this.navigationService.active_fragment.next('network-rail-feedback');
        break;
      

      case window.pageYOffset >= this._features.nativeElement.offsetTop &&
        window.pageYOffset <= this._benefits.nativeElement.offsetTop: 
        this.navigationService.active_fragment.next('features');
        break;
      


      default:
        break;
    
  

【讨论】:

我偶然发现了这个问题,试图优化这段代码,我几年前写的。 stackblitz.com/edit/angular-ivy-eq4j9p 必须计算每个滚动条的可见性有一个缺点。特别是如果你有很多碎片。我期待看到其他解决方案。否则,我会接受这是对我拥有的当前代码的优化。谢谢!

以上是关于滚动经过片段时,Angular 10会获得路由器活动片段吗?的主要内容,如果未能解决你的问题,请参考以下文章

angularJS使用ocLazyLoad实现js延迟加载

为 Angular 子路由添加 scrollPositionRestoration

Angular路由复用策略

如何在Angular2 rc3路由中处理来自oauth重定向url的哈希片段

angular6 相同页面跳转参数不同 页面不刷新问题解决

顺利加载消息Angular 8