如何根据显示的内容更新导航项列表

How to update the navigation item list based on the content displayed

我有这个导航菜单

<ul class="menu-left pl-3">
    <li *ngFor="let period of periods; let i = index">
        <a class="mb-4 fragment-link" [class.active]="selectedIndex === i"
           [ngClass]="{'text-dark font-weight-bold': selectedIndex === i}" (click)="setIndex(i)"
           [routerLink]="['/registrations/list']" fragment="d{{period}}">
            {{period}}
        </a>
    </li>
</ul>

期间是一个学年,例如2017-2018。 在我要添加动态滚动的页面中,我希望在向用户显示的卡片处于该学年时突出显示导航项。用户通常每学年注册 2 个学期(尽管有时只注册一个学期),因此将导航条目与其中一个注册条目绑定不是解决方案。

这是卡片遵循的模式:

<div class="reg_courses_body__main">
          <div *ngFor="let registration of registrations">
            <div id="d{{registration?.registrationYear.alternateName}}">
            <div class="card mt-2 year">
              <div class="card-body">
....
              </div>
           </div>
        </div>
</div>

我试过以下方法

    $(window).scroll(function() {
      const scrollDistance = $(window).scrollTop();
      const elements = document.getElementsByClassName('year');
      const periods = document.getElementsByClassName('fragment-link');
      let j = 0;
      for ( let i = 1; i < elements.length; ++i) {
        j = i;
        if ($(elements.item(i)).position().top - 70 <= scrollDistance) {
          continue;
        } else {
          for ( let k = 0; k < periods.length; ++k ){
            if( elements.item(i).parentElement.id === 'd'.concat(periods.item(k).textContent.replace(/\s+/g, ''))) {
              j = k;
            }
          }
          $('.menu-left li a.active').removeClass('active text-dark font-weight-bold').addClass('text-gray-600');
          $('.menu-left li a').eq(j).addClass('active text-dark font-weight-bold');
        }
      }
  }).scroll();

但它并没有像我预期的那样有效。

我添加了 @HostListener 这样的

@HostListener('window:scroll', ['$event'])
  public onWindowScroll(event: ScrollEvent): void{
    if ( !this.isScrolling ) {
      this.isScrolling = true;
    }
    const currentScroll = $(window).scrollTop();
    const elements = document.getElementsByClassName('year');

    for (let i = 1; i < elements.length; i++) {
      const currentElement = elements.item(i);

      if ($(elements.item(i)).position().top <= currentScroll) {
        this.selectedIndex = this.periods.indexOf(currentElement.parentElement.id.slice(1, currentElement.parentElement.id.length));
        $('.menu-left a.active').removeClass('active text-dark font-weight-bold');
        $('.menu-left a').eq(this.selectedIndex).addClass('active text-dark font-weight-bold');
      }
    }
  }

它使用 class .year 获取元素并检查它们在页面中的位置,如果元素的位置小于或等于当前滚动,它会更新导航菜单,通过删除附加到活动元素的 classes 并将它们附加到活动元素。 selectedIndex 是当前元素的父元素的 id 减去第一个字母的索引,因为这种格式的元素的 ids d{{period}}

非常感谢@khushi 为我指明了正确的方向