Как мне заставить элемент прокручиваться до центра полосы прокрутки при входе на страницу

#javascript #html #angular

#javascript #HTML #угловой

Вопрос:

Я создаю проект Angular, в котором есть компонент «timeline», в котором есть overflow-x: scroll элемент:

 .container {
    width: 30vw;
    height: 100vh;
    background-color: aquamarine;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
}

.timeline-box {
    width: 90%;
    position: relative;
}

.timeline-strip {
    background-color: yellow;
    height: 200px;
    display: flex;
    overflow-x: scroll; 
}

.timeline-box:before {
    content: '';
    position: absolute;
    top: 50%;
    border-top: 2px solid black;
    width: 100%;
    height: 0px;
}

.point {
    margin: 0 40px;
    align-self:center;
}
.point:before {
    content: '';
    position: relative;
    left: 50%;
    border-left: 2px solid black;
    top: 20px;
}  
   <div class="container">
    <div class="timeline-box">
      <div class="timeline-strip">

        <div class="point">1</div>
        <div class="point">2</div>
        <div class="point">3</div>
        <div class="point">4</div>
        <div class="point">5</div>
        <div class="point">6</div>
        <div class="point">7</div>
        <div class="point">8</div>
        <div class="point">9</div>
        <div class="point">10</div>

      </div>
    </div>
  </div>  

Я хочу, чтобы полоса прокрутки .timeline-strip элемента (а не полоса прокрутки самой страницы) автоматически оказывалась посередине, когда пользователь заходит на страницу. Как я могу этого добиться? (Я использую Angular, если это помогает)

Ответ №1:

Вы можете сделать это, взяв scrollWidth свойство минус clientWidth свойство и разделив результат этого на 2. Это будет положение прокрутки на полпути, поэтому вы можете установить это значение для scrollLeft свойства.

Если ваш div содержит изображения, то вы хотите сделать это в событии загрузки окна. В событии document DOMContentLoaded изображения еще не загружены (если не обналичены), и поэтому размер вашего div может измениться при загрузке изображений.

 //Can be document.addEventListener('DOMContentLoaded', () => {}) when you don't care about images and stuff
window.addEventListener('load', () => {
  let scrollElement = document.querySelector('.timeline-strip');
  scrollElement.scrollLeft =  (scrollElement.scrollWidth - scrollElement.clientWidth ) / 2;
});  
 .container {
    width: 30vw;
    height: 100vh;
    background-color: aquamarine;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
}

.timeline-box {
    width: 90%;
    position: relative;
}

.timeline-strip {
    background-color: yellow;
    height: 200px;
    display: flex;
    overflow-x: scroll; 
}

.timeline-box:before {
    content: '';
    position: absolute;
    top: 50%;
    border-top: 2px solid black;
    width: 100%;
    height: 0px;
}

.point {
    margin: 0 40px;
    align-self:center;
}
.point:before {
    content: '';
    position: relative;
    left: 50%;
    border-left: 2px solid black;
    top: 20px;
}  
 <div class="container">
    <div class="timeline-box">
      <div class="timeline-strip">

        <div class="point">1</div>
        <div class="point">2</div>
        <div class="point">3</div>
        <div class="point">4</div>
        <div class="point">5</div>
        <div class="point">6</div>
        <div class="point">7</div>
        <div class="point">8</div>
        <div class="point">9</div>
        <div class="point">10</div>

      </div>
    </div>
  </div>  

Ответ №2:

лично мне не нравится использовать addEventListener, поэтому @ViewChild лучше. Это зависит от того, какой угловой используется

измените ответ от @ng-hobby:

добавьте идентификатор в div временной шкалы:

 <div class="timeline-strip" #timelineStrip >
  

измените ViewChild и переименуйте, если хотите:

 @ViewChild('timelineStrip', {static: false}) timelineStripRef: ElementRef;
  

вы можете использовать scrollTo для timelineStripRef элемента или временной шкалы:

 const width = this.timelineStripRef.nativeElement.clientWidth;
this.timelineStripRef.nativeElement.scrollTo(width/2, 0);
  

Ответ №3:

Я создал образец для вас здесь, на Stackblitz

Итак, попробуйте что-то подобное, используя @viewChild amp; ngAfterViewInit с window.scrollTo() :

app.component.html

 <hello name="{{ name }}"></hello>
<p class="img" #getHeight>
  Start editing to see some magic happen :)
</p>
  

app.component.ts

 import { Component, VERSION, ElementRef, AfterViewInit, ViewChild } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {
  name = 'Angular '   VERSION.major;
  @ViewChild('getHeight', {static: false}) getHeight: ElementRef;
  constructor(private el: ElementRef){}

  ngAfterViewInit() {
    let pageheight = this.getHeight.nativeElement.offsetHeight;
    console.log(pageheight/2)
    window.scrollTo(0, pageheight/2);
  }
}

  

Комментарии:

1. Извините, я должен был уточнить в своем вопросе, я хочу, чтобы полоса прокрутки элемента timeline-strip автоматически центрировалась при входе на страницу, а не полоса прокрутки самой страницы. Теперь я отредактирую вопрос