Angular 5,如何检测用户不活动

Art*_*tul 3 angular

除了使用IdleJS和ngDoCheck(),我们如何在Angular 5中检测用户的不活动状态?

谢谢

小智 13

您可以尝试这样做:

export class AppComponent {

  userActivity;
  userInactive: Subject<any> = new Subject();

  constructor() {
    this.setTimeout();
    this.userInactive.subscribe(() => console.log('user has been inactive for 3s'));
  }

  setTimeout() {
    this.userActivity = setTimeout(() => this.userInactive.next(undefined), 3000);
  }

  @HostListener('window:mousemove') refreshUserState() {
    clearTimeout(this.userActivity);
    this.setTimeout();
  }
}
Run Code Online (Sandbox Code Playgroud)

似乎可以在此堆叠中工作:打开控制台,不要将鼠标移动3秒钟:您会看到消息。

刷新页面,在预览(右侧)上移动鼠标几秒钟:直到停止3秒钟,消息才会弹出。

显然,您可以将其导出到服务中,因为如您所见,我仅使用一个类来执行该操作。

  • 请记住,这假设用户正在使用鼠标。对于移动用户或使用屏幕阅读器或仅使用键盘的用户来说,这可能不太适用。 (3认同)
  • 有用。我刚试过。很棒的答案和你在那里的工作!太感谢了! (2认同)

Bob*_*les 12

解决此问题的服务(而不是作为公认答案的组件)处理触摸、打字和鼠标。在用户闲置 N 秒后以及当他“醒来”时发出事件。适用于 Angular 11:

import { Injectable } from "@angular/core";
import { fromEvent, Subject } from "rxjs";

@Injectable({
    providedIn: 'root',
})
export class IdleService {

  public idle$: Subject<boolean> = new Subject();
  public wake$: Subject<boolean> = new Subject();

  isIdle = false;
  private idleAfterSeconds = 10;
  private countDown;

  constructor() {
    // Setup events
    fromEvent(document, 'mousemove').subscribe(() => this.onInteraction());
    fromEvent(document, 'touchstart').subscribe(() => this.onInteraction());
    fromEvent(document, 'keydown').subscribe(() => this.onInteraction());
  }

  onInteraction() {
    // Is idle and interacting, emit Wake
    if (this.isIdle) {
      this.isIdle = false;
      this.wake$.next(true);
    }

    // User interaction, reset start-idle-timer
    clearTimeout(this.countDown);
    this.countDown = setTimeout(() => {
      // Countdown done without interaction - emit Idle
      this.isIdle = true;
      this.idle$.next(true);
    }, this.idleAfterSeconds * 1_000)
  }
}
Run Code Online (Sandbox Code Playgroud)

用法,注入构造函数并使用:

constructor(private idleService: IdleService) {  
  idleService.idle$.subscribe(s => console.log('im idle, zzz'));
  idleService.wake$.subscribe(s => console.log('im awake!'));
}
Run Code Online (Sandbox Code Playgroud)

  • 可能足以将“Subject”更改为“BehaviorSubject”,其初始值表示应用程序启动时的“唤醒”状态,以防止在“idle$”和“wake$”的订阅者中出现错误的“空闲”状态应用程序刚刚启动。 (3认同)
  • 对您的解决方案的一个很好的补充是使服务通过构造函数(传入)获取空闲持续时间,而不是对其进行硬编码。否则很棒的工作 (2认同)

dan*_*ali 5

这个解决方案对我来说效果很好。我所面临的接受答案的问题是,它只关注鼠标事件,而不关注键盘按键事件

    userActivity;
    userInactive: Subject<any> = new Subject();

    constructor( ) {
        
        this.setTimeout();
        this.userInactive.subscribe(() => {
        this.router.navigate(['/auth/lock']);
        });
       
        }
Run Code Online (Sandbox Code Playgroud)
  • 这些事件检查用户是否在特定时间内处于空闲状态,然后订阅不同的(锁定)屏幕

     keyPress(event: KeyboardEvent): void {
         clearTimeout(this.userActivity);
         this.setTimeout();
     }
     setTimeout(): void {
         this.userActivity = setTimeout(() => this.userInactive.next(undefined), 900000);
     }
    
     @HostListener('window:mousemove') refreshUserState() {
         clearTimeout(this.userActivity);
         this.setTimeout();
     }
    
    Run Code Online (Sandbox Code Playgroud)

  • @ThomasJahncke 非常感谢。这确实给了我一个见解:) (2认同)