Search code examples
angularscrollscrollbar

Sync two scroll bars in Angular


I’m trying to synchronize two scroll bars:

My code

The sync it’s working when I scroll with the first scroll bar but not with the second scroll bar. How can I solve it? I running out of ideas. To use a library it's not an option for me.

HTML

<div style="overflow: auto" (scroll)="updateScroll()" #scrollOne>
  <div style="width: 1300px; border: 1px solid red; height: 230px">Scroll bar One</div>
</div>

<div style="overflow: auto"  #scrollTwo >
  <div style="width: 1300px; border: 1px solid red; height: 230px">Scroll bar Two</div>
</div>

TS FILE

@ViewChild('scrollOne') scrollOne: ElementRef;
@ViewChild('scrollTwo') scrollTwo: ElementRef;

updateScroll(){
    const scrollOne = this.scrollOne.nativeElement as HTMLElement;
    const scrollTwo = this.scrollTwo.nativeElement as HTMLElement;

    // do logic and set
    scrollTwo.scrollLeft = scrollOne.scrollLeft;
}

Thanks in advance


Solution

  • Since you just want that non-focused scrollbar behaves as the focused one, your initial idea is just fine: scrollTwo.scrollLeft = scrollOne.scrollLeft; is a good start. That also means that for the other scrollbar (scrollTwo) you should do the same.

    However, duplicating the code is bad practice and actually not needed: you can call the same method for scroll event on both scrollbars, passing the scrollbar elements in opposite order:

    (scroll)="updateScroll(scrollOne,scrollTwo)" on scrollOne, and (scroll)="updateScroll(scrollTwo,scrollOne)" on scrollTwo

    And then modify your updateScroll method to:

    updateScroll(bar1: any, bar2: any) {
        bar2.scrollLeft = bar1.scrollLeft;
    }
    

    Nothing else is needed: scrollbars are already passed as html elements so the method only needs to handle the order (which bar is setting the value and which one is receiving it), which is done by the callers.

    Here's a stackblitz.