Angular 4 - 当 div 进入视口(viewport)时如何触发动画?

标签 angular animation scroll visible

我一直在使用 Angular 4 构建一个新网站,我正在尝试重新创建一个效果,当 div 变得可见时(当您向下滚动屏幕时)然后可以触发一个 Angular 动画来滑动div 形式的两侧。

过去我已经能够在 Angular 4 之外使用 jQuery 来做到这一点,但我想尝试使用原生 Angular 4 动画来创建相同的效果。

任何人都可以向我提供有关如何在 div 进入 View 时触发动画的建议(即,当它进入视口(viewport)时向下滚动到页面的下部?)。我已经编写了幻灯片动画,但我不知道如何在 div 稍后对视口(viewport)可见时通过滚动来触发它。

谢谢大家!

最佳答案

我已经创建了一个指令,一旦元素完全在 View 内或者它的上边缘已经到达 View 的上边缘,它就会发出一个事件。

这是一个傻瓜:https://embed.plnkr.co/mlez1dXjR87FNBHXq1YM/

它是这样使用的:

<div (appear)="onAppear()">...</div>

这是指令:

import {
  ElementRef, Output, Directive, AfterViewInit, OnDestroy, EventEmitter
} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Subscription} from 'rxjs/Subscription';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/startWith';

@Directive({
  selector: '[appear]'
})
export class AppearDirective implements AfterViewInit, OnDestroy {
  @Output()
  appear: EventEmitter<void>;

  elementPos: number;
  elementHeight: number;

  scrollPos: number;
  windowHeight: number;

  subscriptionScroll: Subscription;
  subscriptionResize: Subscription;

  constructor(private element: ElementRef){
    this.appear = new EventEmitter<void>();
  }

  saveDimensions() {
    this.elementPos = this.getOffsetTop(this.element.nativeElement);
    this.elementHeight = this.element.nativeElement.offsetHeight;
    this.windowHeight = window.innerHeight;
  }
  saveScrollPos() {
    this.scrollPos = window.scrollY;
  }
  getOffsetTop(element: any){
    let offsetTop = element.offsetTop || 0;
    if(element.offsetParent){
      offsetTop += this.getOffsetTop(element.offsetParent);
    }
    return offsetTop;
  }
  checkVisibility(){
    if(this.isVisible()){
      // double check dimensions (due to async loaded contents, e.g. images)
      this.saveDimensions();
      if(this.isVisible()){
        this.unsubscribe();
        this.appear.emit();
      }
    }
  }
  isVisible(){
    return this.scrollPos >= this.elementPos || (this.scrollPos + this.windowHeight) >= (this.elementPos + this.elementHeight);
  }

  subscribe(){
    this.subscriptionScroll = Observable.fromEvent(window, 'scroll').startWith(null)
      .subscribe(() => {
        this.saveScrollPos();
        this.checkVisibility();
      });
    this.subscriptionResize = Observable.fromEvent(window, 'resize').startWith(null)
      .subscribe(() => {
        this.saveDimensions();
        this.checkVisibility();
      });
  }
  unsubscribe(){
    if(this.subscriptionScroll){
      this.subscriptionScroll.unsubscribe();
    }
    if(this.subscriptionResize){
      this.subscriptionResize.unsubscribe();
    }
  }

  ngAfterViewInit(){
    this.subscribe();
  }
  ngOnDestroy(){
    this.unsubscribe();
  }
}

关于Angular 4 - 当 div 进入视口(viewport)时如何触发动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43573489/

相关文章:

ios - 如何更改uipagecontrol的动画页数?

Android - 用于交错 GridView 的 OnScrollListener

jquery - 固定 float 元素停在页脚

css - 在下拉菜单选项上添加滚动条

angular - 我可以在我的计算机中使用多个 Angular 版本吗?

html - 调整窗口大小时,Bootstrap 表单控制对齐方式

css - 如何让 <select> 显示内联?

html - Angular index和app.component.html应该怎么写?

javascript - Angular JS 1.2 - 使用 ng-show 动画化子元素

iphone - 如何设置键盘动画时间