Reputation: 6752
I'm struggling with creation of this observable. I have a hide-able element in my Angular
app. When the user leaves with mouse over this element and he doesn't enters lets say in 500ms, the element should hide.
The marble diagram:
onleave --x-------x------------------------>
onenter -----x----------------------------->
<--500ms-->
_________________________________________
hide ---------------------x------------->
const leave$ = fromEvent(this.selector.nativeElement,"mouseleave");
const enter$ = fromEvent(this.selector.nativeElement,"mouseenter");
const hide$ = // ToDo: implement logic
EDIT:
I've created an observable, but it does't work the way I would like:
const leave$ = fromEvent(this.backgroundSelector.nativeElement, "mouseleave");
const enter$ = fromEvent(this.backgroundSelector.nativeElement, "mouseenter");
const hide$ = leave$.pipe(
mergeMap(event =>
of(event).pipe(
delay(500),
takeUntil(enter$)
)
)
);
hide$.pipe(takeUntil(this.destroy$)).subscribe(_ => this.hideSelector());
The issue is, the element is hiding only when I return with mouse cursor after 500ms.
Upvotes: 2
Views: 340
Reputation: 1846
You can use debounceTime operator on mouseleave event. As mentioned at documentation
DebounceTime discard emitted values that take less than the specified time between output
On mouseenter event you need to discard emitted values from mouseleave event. And for this case you can simple use switchMap operator, which will discard inner observable emit values.
const main = document.getElementById('main');
const content = document.getElementById('content');
fromEvent(main, 'mouseenter')
.pipe(
switchMap(event => {
content.style.display = 'block';
return fromEvent(main, 'mouseleave').pipe(debounceTime(500));
}))
.subscribe(val => {
content.style.display = 'none';
});
Here is example on Stackblitz
Upvotes: 1