Search code examples
angularpopup

How can I delay the timer when hovering over an object?


I have a pop-up window that is open for some time specified in the timer. I need the timer to stop when I hover the cursor over the window, and continue when I move the cursor away. this is what my setTimeout looks like:

if(this.toast.timeout){
      setTimeout(() => {
        this.close()
      }, this.toast.timeout);
    }

I was thinking of using clearTimeout, but it will completely stop the timer and I do not know how to start it again from the right place. Please tell me what I can do in this situation.


Solution

  • I think that RxJS would be the perfect candidate for your use case.

    Here is a simple example you can use to achieve what you want. Once you start to get more comfortable with it, you can improve this example :

    // Get the HTML elements
    const toast = document.querySelector('.toast');
    const placeholder = document.querySelector('.duration');
    
    // Declare useful variables
    let totalduration = 0;
    let register = true;
    
    // Create event emitters
    const timer = rxjs.timer(0, 100);
    const entering = rxjs.fromEvent(toast, 'mouseenter').pipe(rxjs.startWith(null));
    const leaving = rxjs.fromEvent(toast, 'mouseleave').pipe(rxjs.startWith(null));
    
    // Listen to all event emitters
    rxjs.combineLatest({
      timer,
      entering,
      leaving,
    }).pipe(
      // Return if the event should register or not
      rxjs.map(() => register),
      // Only do the .subscribe if the value of register is true
      rxjs.filter(Boolean),
    ).subscribe(() => {
      totalduration += 0.1;
      placeholder.textContent = (Math.round(totalduration * 100) / 100) + 's';
    });
    
    // Listen to mouse events and change the register value accordingly
    entering.subscribe(() => (register = false));
    leaving.subscribe(() => (register = true));
    .toast {
      background-color: salmon;
      padding: 1rem;
      box-sizing: border-box;
      display: inline-block;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.8.1/rxjs.umd.min.js"></script>
    
    <div class="toast">
      Duration : <span class="duration">0s</span>
    </div>