gpt4 book ai didi

javascript - 仅当另一个可观察对象在过去两秒内未发出时才从可观察对象发出

转载 作者:行者123 更新时间:2023-11-28 03:02:51 25 4
gpt4 key购买 nike

注意:类似的问题是here但它似乎并没有以我可以应用的明显方式得到回答。

问题:我有一个“转到顶部”按钮,其功能是将用户滚动到页面顶部。当用户实际位于顶部时,它不应该是可见的。

它的可见性目前是通过动画不透明度属性来处理的,但由于显示:没有应用,所以可以与它进行交互。所以我必须找到一种方法,当不透明度为0时,显示:无应用。

Angular 中的第一个实现是执行以下操作:

    @HostListener('window:scroll', ['$event'])
scrolled(_event: Event) {
if (window.pageYOffset === 0) {
setTimeout(() => (this.noClick = true), 1000);
} else {
this.noClick = false;
}

this.show = window.pageYOffset > 0;
}

其中 noClickshow 是 bool 值,并且 noClick 应用于设置 display:none 和 show< 的类 应用于动画不透明度。

但是存在一个竞争条件,即用户可以在滚动到 0 后向下滚动,并且延迟仍然可以将 noClick 设置为 true。

我想考虑使用 Observable 来解决这个问题。

如果我有两个主题:

displayNone = new Subject<boolean>();   // only contains true values
displaySome = new Subject<boolean>(); // only contains false values

和一些事件代码:

    @HostListener('window:scroll', ['$event'])
scrolled(_event: Event) {
if (window.pageYOffset === 0) {
this.displayNone.next(true);
} else {
this.displaySome.next(false);
}

this.show = window.pageYOffset > 0;
}

我需要为 displayNone 功能构造一个可观察对象,其中如果 displayNone 延迟 1000 毫秒(动画时间),并且在这段时间内 displaySome 发出,它必须忽略 displayNone

我目前能想到的最接近的是这样的:

race(this.displaySome, this.displayNone.pipe(delay(1000)))

但我的理解是,只需要评估一次就可以决定通过哪一个。我需要不断地评估它。

最佳答案

您不需要两个 Observables 来显示/隐藏带有动画的按钮。问题的最佳解决方案与问题的答案不同。我正在尝试回答这两个问题。

仅当另一个 Observable 在最后 X 毫秒内未发出时才发出

const X = 1000;
const obs$ = source$.pipe(
// emit values on a new inner Observable when the otherObservable$ emits
window(otherObservable$),
// skip all values on this inner Observable until a given time has passed
// (but not for the first inner Observable created before otherObservable$ emits)
mergeMap((w, i) => i == 0 ? w : w.pipe(skipUntil(timer(X))))
);

根据滚动事件显示/隐藏按钮

  1. 从滚动事件创建一个 Observable 并映射到一个 bool 值,指示是否显示或隐藏按钮。
hasScrolledDown$: Observable<boolean>;

ngOnInit() {
this.hasScrolledDown$ = fromEvent(window, 'scroll').pipe(
throttleTime(20),
map(() => window.pageYOffset > 50)
)
}
  • 使用 ngIf 根据 Observable 中的值显示/隐藏按钮。
  • <button *ngIf="hasScrolledDown$ | async">
  • (可选)进入离开状态更改添加动画。
  • <button *ngIf="hasScrolledDown$ | async" [@fadeAnimation]>
    export const fadeOutAnimation = animation([
    style({ opacity: 1 }),
    animate('200ms', style({ opacity: 0 }))
    ])

    export const fadeInAnimation = animation([
    style({ opacity: 0 }),
    animate('200ms', style({ opacity: 1 }))
    ])

    @Component({
    selector: 'button-overview-example',
    templateUrl: 'button-overview-example.html',
    styleUrls: ['button-overview-example.css'],
    animations: [
    trigger('fadeAnimation', [
    transition(':enter', [useAnimation(fadeInAnimation)]),
    transition(':leave', [useAnimation(fadeOutAnimation)])
    ])
    ],
    })

    Demo

    关于javascript - 仅当另一个可观察对象在过去两秒内未发出时才从可观察对象发出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60828644/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com