【问题标题】:How to change Header section on scrolling in Angular?如何更改 Angular 中滚动的标题部分?
【发布时间】:2019-06-01 23:48:18
【问题描述】:

我想在以角度滚动水平侧边栏时更改标题部分。 通过使用 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

【问题讨论】:

  • 请内联发布代码。

标签: html css angular typescript angular-material


【解决方案1】:

您的解决方案仅在用户向下滚动超过给定值时显示 header-2,但不会在用户向上滚动时再次显示 header-1,就像在您发布的演示页面上一样。只有当用户滚动回顶部时,Header-1 才会再次出现。

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

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

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();
  }

}

我稍微更改了 HTML,但您也可以使用不同的设置,然后在上面的代码中设置相应滚动的元素,或者只是在 window 上监听滚动事件。

<div class="headerWrapper">
  <mat-toolbar class="header" color="primary" [@scrollAnimation]="isHeader1Visible">
    <mat-toolbar-row>
      <span>Header 1</span>
    </mat-toolbar-row>
  </mat-toolbar>

  <mat-toolbar class="header" color="secondary" [@scrollAnimation]="isHeader2Visible">
    <mat-toolbar-row>
      <span>Header 2</span>
    </mat-toolbar-row>
  </mat-toolbar>
</div>
<div class="scrollWrapper">
  <div class="scrollContent">
  ...
  </div>
</div>

【讨论】:

  • stackblitz.com/edit/… 对于上面的如果我们需要为父滚动保持相同的标题效果,我们如何实现。而不是创建内容
  • 我不确定你的意思。你想观察哪个元素的滚动事件?
  • 滚动标题时要更改的父标题是链接stackblitz.com/edit/angular-pj5rjj-wwhv1t?embed=1&file=app/…
  • @poojariraj '父标题'是什么意思?您发布的 stackblitz 按预期工作。请使用您的应用程序的确切 html 设置发布 stackblitz,以便我可以为您提供帮助。正如我在回答中所写,如果您需要的话,您可以随时收听 window 上的滚动事件。
  • @friddo 我在这里分享 stackblitz 链接:stackblitz.com/edit/angular-pj5rjj-zk73b1?embed=1&file=app/… 在此示例中,当我们滚动父滚动和子滚动时,我们有两个滚动条,我需要显示任何一个滚动条,当我们滚动时要更改的标题应该向上滚动到最后一个内容。提前感谢
【解决方案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;
  }
}

【讨论】:

  • 我猜有点跑题了,但是在代码中使用这样的窗口是否与平台无关(最佳实践)?有没有其他方法可以避免它?谢谢。
  • @DawidZbiński 如果滚动发生在某个元素内,您可以改为收听Element.scrollTop
  • @fridoo Iam 有一个小的查询,当我们在点击按钮加载加载数据时获取数据并使用数据来禁用该代码的网页是否有病分享你请帮助我堆栈:blitz 链接:单击按钮后覆盖加载器要加载的 css 类,一旦获取数据 css 覆盖加载器将成为 dissaper 堆栈溢出链接:stackoverflow.com/questions/54439571/…
猜你喜欢
  • 2014-01-02
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
  • 1970-01-01
  • 1970-01-01
  • 2015-07-25
相关资源
最近更新 更多