user1380431
user1380431

Reputation: 57

Angular 2+ - How to combined mouseover, mouseout and click events on the same element?

I'm trying to implement a navigation link functionality where if the user mouseover it opens up and if the user mousesout, then it closes. But also if the user clicks on the link then it toggles it. The issue I have is the events conflict with one another and it causes flickering of the nav dropdown. The click toggle closes it, but at the same time the mouse is hovering over it which indicates to open.

real life example - https://www.td.com/ca/en/personal-banking/ - the way "products" or "solutions" work in the nav.

Upvotes: 0

Views: 1509

Answers (1)

waterplea
waterplea

Reputation: 3641

  1. You should use mouseenter and mouseleave instead of your events so they won't not trigger on nested tags.
  2. I would suggest to make an Observable of openness using RxJs's fromEvent and piping all your events into one resulting boolean.

Here, I've made a stackblitz for you showing what I mean by that: https://stackblitz.com/edit/angular-4ntjhm?file=src%2Fapp%2Fhello.component.ts

Observable part:

    const mouseenter$ = fromEvent(nativeElement, 'mouseenter');
    const mouseleave$ = fromEvent(nativeElement, 'mouseleave');
    const click$ = fromEvent(nativeElement, 'click');

    this.open$ = merge(
      mouseenter$.pipe(mapTo(true)),
      mouseleave$.pipe(mapTo(false)),
      click$.pipe(mapTo(null)),
    ).pipe(
      scan((acc, current) => current === null ? !acc : current, false),
      startWith(false),
      distinctUntilChanged(),
    );

Basically you map enter to true and leave to false and on click you toggle the previous value.

Upvotes: 1

Related Questions