【发布时间】:2020-03-24 09:56:40
【问题描述】:
注意:类似的问题是 here,但似乎没有以我可以申请的明显方式回答。
问题:我有一个“转到顶部”按钮,其功能是将用户滚动到页面顶部。当用户实际位于顶部时,它不应该是可见的。
它的可见性目前是通过动画不透明度属性处理的,但由于 display: none 未被应用,它可以与之交互。所以我必须找到一种方法来显示:不透明度为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;
}
其中noClick 和show 是布尔值,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 功能构造一个 observable,如果 displayNone 延迟 1000 毫秒(动画时间)并且在那段时间 displaySome 发出,它必须忽略 displayNone。
我目前能来的最接近的是这样的:
race(this.displaySome, this.displayNone.pipe(delay(1000)))
但我的理解是,它只需要评估一次并决定通过哪一个。我需要不断对其进行评估。
【问题讨论】:
-
1000ms 延迟有什么作用?
-
另外,你能创建一个简单的堆栈闪电战来演示这个问题吗
-
我很不清楚为什么你有两个主题。看起来您可能只有一个发射
true/false取决于您是否要显示按钮。或者也许有什么我没看到... -
@KurtHamilton 1000 毫秒的延迟是 opacity 属性上动画的持续时间,因为 display: none 不会动画。
-
@martin 这两个主题是因为其中一个必须延迟才能让动画有时间工作,而另一个应该覆盖它。
标签: javascript angular animation rxjs