如何在Angular中滚动时更改Header部分?

时间:2019-01-07 10:09:15

标签: html css angular typescript angular-material

我想在以角度滚动水平边栏时更改标题部分。 通过使用hostlister,我已经实现了此目的,但是它没有按预期工作。

example.ts文件中的代码

import {Component,HostListener} from '@angular/core';

/** @title Implicit main content with two sidenavs */
@Component({
  selector: 'sidenav-position-example',
  templateUrl: 'sidenav-position-example.html',
  styleUrls: ['sidenav-position-example.css'],
})
@HostListener('window:scroll', [])
export class SidenavPositionExample {
scrolled : boolean =  true;
onWindowScroll() {
    this.scrolled = window.pageYOffset >48;
    }
}

html代码

<div style="min-height: 150vh;"> <!-- Set minimum height to force a scrollbar -->
    <mat-toolbar color="primary">
        <mat-toolbar-row>
            <span>Header 1</span>
        </mat-toolbar-row>
    </mat-toolbar>

    <mat-toolbar color="secondary" style="position: fixed; top: 0;" *ngIf="scrolled">
        <mat-toolbar-row>
            <span>Header 2</span>
        </mat-toolbar-row>
    </mat-toolbar>
</div>

A Stackblitz of what I tried

A demo of what I want

2 个答案:

答案 0 :(得分:2)

HostListener 不应放在组件类中,而应放在类方法之内

这部分是错误的

@HostListener('window:scroll', [])
export class SidenavPositionExample {

您的组件类应该是这样

import { Component, HostListener } from '@angular/core';

/** @title Implicit main content with two sidenavs */
@Component({
  selector: 'sidenav-position-example',
  templateUrl: 'sidenav-position-example.html',
  styleUrls: ['sidenav-position-example.css'],
})
export class SidenavPositionExample {
  scrolled: boolean = false;

  // for initialization
  constructor() {
    this.scrolled = window.pageYOffset > 48;
  }


  @HostListener('window:scroll', [])
  onWindowScroll() {
    this.scrolled = window.pageYOffset > 48;
  }
}

答案 1 :(得分:0)

您的解决方案仅在用户向下滚动到给定值以下时才显示标头2,但在用户向上滚动时(如您发布的演示页上),不会立即显示标头1。仅当用户滚动回到顶部时,标题1才会再次出现。

要在用户向上滚动时立即将header-1滑回,则必须在触发滚动事件时确定当前滚动方向。为此,您可以创建可观察到的滚动位置流,将它们映射到UP / DOWN方向,并相应地设置标题状态。然后使用动画根据观察到的标题状态将标题移入和移出。

https://stackblitz.com/edit/angular-pj5rjj-8asowc

A a;
foo1( a );  // caller copies, foo1 moves
foo2( a );  // foo2 copies

我稍微改变了HTML,但是您也可以使用其他设置,然后设置上面代码中相应滚动的元素,或者只是监听import { Component, HostListener, AfterViewInit, OnDestroy } from '@angular/core'; import { fromEvent, Subject } from 'rxjs'; import { distinctUntilChanged, map, pairwise, takeUntil, throttleTime } from 'rxjs/operators'; import { animate, state, style, transition, trigger } from '@angular/animations'; export enum VisibilityState { Visible = 'visible', Hidden = 'hidden' } export enum Direction { None = 'None', Up = 'Up', Down = 'Down' } @Component({ selector: 'sidenav-position-example', templateUrl: 'sidenav-position-example.html', styleUrls: ['sidenav-position-example.css'], animations: [ trigger('scrollAnimation', [ state(VisibilityState.Visible, style({ transform: 'translateY(0)' })), state(VisibilityState.Hidden, style({ transform: 'translateY(-64px)' })), // adjust this to the height of your header transition(`${VisibilityState.Visible} => ${VisibilityState.Hidden}`, animate('250ms')), transition(`${VisibilityState.Hidden} => ${VisibilityState.Visible}`, animate('250ms')) ]) ] }) export class SidenavPositionExample implements AfterViewInit, OnDestroy { private destroy$: Subject<boolean> = new Subject<boolean>(); isHeader1Visible = VisibilityState.Visible; isHeader2Visible = VisibilityState.Hidden; slideHeader2InAtPosition = 30; ngAfterViewInit() { // create an observable stream of scroll positions and map them to UP / DOWN directions const content = document.querySelector('.scrollWrapper'); // if the scroll events happen on your window you could use 'window' instead of // 'content' here const scroll$ = fromEvent(content, 'scroll').pipe( throttleTime(10), // if you used 'window' above replace 'content.scrollTop' with 'window.pageYOffset' map(() => content.scrollTop), pairwise(), map(([y1, y2]): Direction => (y2 < y1 ? Direction.Up : (y2 > this.slideHeader2InAtPosition ? Direction.Down : Direction.None))), distinctUntilChanged(), takeUntil(this.destroy$) ); // subscribe to the UP / DOWN scroll direction stream and set the header state accordingly scroll$.subscribe(dir => { if (dir === Direction.Down) { // scrolling down this.isHeader1Visible = VisibilityState.Hidden; this.isHeader2Visible = VisibilityState.Visible; } else { // scrolling up this.isHeader1Visible = VisibilityState.Visible; this.isHeader2Visible = VisibilityState.Hidden; } }); } ngOnDestroy() { this.destroy$.next(true); this.destroy$.unsubscribe(); } } 上的滚动事件。

window