【问题标题】:How do I make an element scroll to the center of the scroll bar upon entering the page进入页面后如何使元素滚动到滚动条的中心
【发布时间】:2020-10-05 23:14:00
【问题描述】:

我正在制作一个 Angular 项目,它有一个“时间线”组件,它有一个 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)

【问题讨论】:

    标签: javascript html angular


    【解决方案1】:

    您可以通过将scrollWidth 属性减去clientWidth 属性并将其结果除以2 来实现。这将是滚动位置的一半,因此您可以将此值设置为scrollLeft 属性。

    如果您的 div 包含图像,那么您希望在窗口加载事件上执行此操作。在文档 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 中添加一个 id:

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

      根据需要修改 viewChild 并重命名:

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

      您可以在 timelineStripRef 元素或时间轴上使用 scrollTo:

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

      【讨论】:

        【解决方案3】:

        我在Stackblitz为您创建了一个示例

        所以,尝试使用 @viewChildngAfterViewInitwindow.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);
          }
        }
        
        

        【讨论】:

        • 对不起,我应该在我的问题中澄清一下,我希望时间轴条元素的滚动条在进入页面时自动居中,而不是页面本身的滚动条。我现在将编辑问题
        猜你喜欢
        • 1970-01-01
        • 2020-11-13
        • 2021-03-21
        • 1970-01-01
        • 2015-06-22
        • 1970-01-01
        • 2013-12-08
        • 1970-01-01
        • 2011-11-27
        相关资源
        最近更新 更多