RB50
RB50

Reputation: 63

Trouble using scrollIntoView with index

I am able to loop through an array of items and get each item. What I want to do is to click a link on the HTML page and go to one of the elements in the array on the same page.

So far, I have been able to click a link and scroll to ALL items in the UI, rather than each one depending on which link I click. I am so close, but my head is spinning. I have tried every combination of the variable with the index I can think of. Can anyone shed light on this for me?

JavaScript

  **scrollToContent()** {
    let elCollectionArr = Array.from(document.querySelectorAll('.item-heading')); 

    elCollectionArr.forEach((item) => {
      item.scrollIntoView({ behavior: "smooth" });
      console.log(item);
    })    

  }

HTML

<ul class="cbds-c-tabs-v2__list-nav" 
    [ngClass]="isTabNavVisible ? 'cbds-u-display__none' : ''">
    <li 
      *ngFor="let item of items, index as index">
      <a 
        **(click)="scrollToContent()" **
        id="cbds-tabs-v2-mobile__list-item-{{ uid + index }}"
        class="cbds-tabs-v2-mobile__list-item">
        {{ item.tabLabel }}
      </a>
    </li>
  </ul>

  <div 
    id="cbds-tabs-v2-mobile" 
    class="cbds-c-tabs-v2-mobile" 
    [ngClass]="isTabNavVisible ? 'cbds-u-display__none' : ''">

    <div 
      class="cbds-c-mobile__item" 
      *ngFor="let item of items, index as index" 
      id="{{ uid + index }}" 
      tabindex="-1">

      <h3 class="item-heading">
        {{ item.tabLabel }}
      </h3>

      <div 
        [innerHTML]="item.tabPanel" 
        class="{{ mobilePanelId }} {{ classes }}">
      </div>
    </div>
  </div>

I tried using the index inside of the forEach method, but item[index] is causing a type error...

'Element implicitly has an 'any' type because expression of type 'number' can't be used to index type 'Element'. No index signature with a parameter of type 'number' was found on type 'Element'.

scrollToContent() {
    let elCollectionArr = Array.from(document.querySelectorAll('.item-heading')); 

    elCollectionArr.forEach((item, index) => {
      item[index].scrollIntoView({ behavior: "smooth" });
      console.log(item);
    })    

  }```

Upvotes: 0

Views: 61

Answers (1)

Naren Murali
Naren Murali

Reputation: 58071

First add a template reference variable on the item you want to scroll. Also pass in the index to the scroll function.

  <ul class="cbds-c-tabs-v2__list-nav" 
    [ngClass]="isTabNavVisible ? 'cbds-u-display__none' : ''">
    <li 
      *ngFor="let item of items, index as index">
      <a 
        **(click)="scrollToContent(index)" **
        id="cbds-tabs-v2-mobile__list-item-{{ uid + index }}"
        class="cbds-tabs-v2-mobile__list-item">
        {{ item.tabLabel }}
      </a>
    </li>
  </ul>
  ...

  ...
  <h3 class="item-heading" #heading>
    {{ item.tabLabel }}
  </h3>
  ...

Then take ViewChildren of all the headings.

...
@ViewChildren('heading') headings: QueryList<ElementRef<any>>;
...

...
scrollToContent(index: number) {
    const headingsArr = this.headings.toArray(); 
    const heading = headingsArr?.[index];
    if(heading) {
      heading.scrollIntoView({ behavior: "smooth" });
    }
}

Upvotes: 1

Related Questions