【问题标题】:Angular detect when scroll reached certain point滚动到达某个点时的角度检测
【发布时间】:2020-01-19 07:17:18
【问题描述】:

我正在尝试达到以下效果:
第一个容器,其中有一个名为.top-container 的类,其高度约为一页半。一开始,用户应该能够滚动到这个容器的末尾,但是一旦他到达它,容器就会变成fixed,并且下面的元素应该通过滚动与它重叠。

我的方法是检测用户何时到达顶部容器的末端,然后将其位置更改为固定。 但我如何检测用户何时到达某个滚动点?

还有其他方法可以达到预期的效果吗?

我的代码:

<div class="container-fluid px-0 top-container">

  <div class="container-fluid bg-test justify-content-center min-vh-100 d-flex">
    <h1 class="align-self-center">PURE</h1>
  </div>

  <div class="container-fluid justify-content-center d-flex collections" *ngIf="collections">
    <div class="row align-self-center justify-content-around">
      <div class="col-12 mb-5 text-center">
        <h1>ALL COLLECTIONS</h1>
      </div>
      <div class="col-3" *ngFor="let collection of collections">
        <div class="flex-row">
          <div class="col-12 text-center">
            <h4>{{collection.name}}</h4>
            <p>- {{collection.desc}} -</p>
          </div>
          <div class="col-12 d-flex justify-content-center">
            <img [src]="collection.image" [alt]="collection.name" class="w-75 align-self-center">
          </div>
        </div>
      </div>
    </div>
  </div>

</div>

<div class="padding-top">
  <app-slider></app-slider>
  <app-presentation></app-presentation>
</div>

CSS:

.top-container {
  background-color: #EDEDED;

  .collections {
    padding: 5%;
    background-color: white;
    h1 {
      font-family: "Zuric Light";
      text-transform: uppercase;
      color: #D3072A;
    }
    h4 {
      font-family: "Zuric Light";
      text-transform: uppercase;
    }
    p {
      font-family: "Zuric Light";
    }
  }

  .bg-test {
    background-image: url("/assets/images/products/pure/pure-upper-side-red.png");
    background-position: bottom left;
    background-size: contain;
    background-repeat: no-repeat;

    h1 {
      line-height: 1;
      margin: 0;
      font-family: "Zuric Bold";
      color: white;
      font-size: 200px;
      text-transform: uppercase;
      &::first-letter {
        margin-left: -0.05em;
      }
    }
    p {
      color: white;
      font-family: "Zuric Light";
      font-size: 30px;
    }
  }
}

【问题讨论】:

    标签: html css angular typescript


    【解决方案1】:

    通过使用 fromEvent 创建一个可观察的事件并使用 sampleTime 来防止有数千个值

    ,尝试这样的方法来获取滚动位置
    import { fromEvent } from 'rxjs';
    import { map, sampleTime } from 'rxjs/operators'; 
    ...
    ngAfterViewInit(): void {
      const tracker = document.querySelector('.yourElement'); // get your element by css class
      const scroll$ = fromEvent(tracker, 'scroll').pipe(
       sampleTime(300), // to prevent getting multiple values in a milisecond
       map(() => tracker.scrollTop)
      );
      let scrollSubscription = windowYOffsetObservable.subscribe((scrollPos) => {
        console.log(scrollPos); // get scroll position
        // you can do your check here
      });
    }
    

    【讨论】:

    • 谢谢。抱歉这个愚蠢的问题 - 但我该把代码放在哪里?因为只需添加它,例如AfterViewInit 或 HostListener 不会记录任何内容。
    【解决方案2】:

    尝试使用@HostListener 监听滚动事件,直到容器结束。然后,调用你的函数。

    【讨论】:

    • 如何只在容器结束之前收听@HostListener?
    【解决方案3】:

    这对Intersection Observer (IO). 来说是件好事,有了它,您可以检查一个元素与另一个元素或屏幕的交叉程度。监听滚动事件和计算元素的位置可能会导致性能下降,因此建议使用 IO 来解决此类问题。

    首先你必须为你的 IO 定义你的选项(你可以有多个 IO)

    let options = {
      rootMargin: '0px',
      threshold: 1.0
    }
    
    let observer = new IntersectionObserver(callback, options);
    

    其次,您定义要观看的元素:

    let target = document.querySelector('#yourHeader');
    observer.observe(target);
    

    最后一步是定义回调函数以及当元素进入视图/离开视图时应该发生什么:

    let callback = (entries, observer) => { 
      entries.forEach(entry => {
        // Each entry describes an intersection change for one observed
        // target element
      });
    };
    

    如果需要,您还可以使用this polyfill from w3c 来支持旧版浏览器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 2012-05-07
      • 1970-01-01
      • 1970-01-01
      • 2019-07-13
      • 2019-06-16
      相关资源
      最近更新 更多