| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- export class InactivityTimer {
- constructor(options = {}) {
- this.defaults = {
- timeout: 30000, // 默认30秒超时
- warningTime: 5000, // 提前5秒警告
- onTimeout: () => console.log('Timeout callback'),
- onWarning: () => console.log('Warning callback'),
- onReset: () => {},
- onStart: () => {},
- onStop: () => {}
- };
-
- this.config = { ...this.defaults, ...options };
- this.timer = null;
- this.timeLeft = this.config.timeout;
- this.isRunning = false;
- this.isPaused = false;
- this.warningTriggered = false;
- this.startTime = null;
- this.pageVisible = true;
-
- this.init();
- }
- init() {
- document.addEventListener('visibilitychange', () => this.handleVisibilityChange());
- this.setupActivityListeners();
- }
- setupActivityListeners() {
- ['mousemove', 'keydown', 'click', 'scroll', 'touchstart'].forEach(event => {
- document.addEventListener(event, () => this.handleUserActivity());
- });
- }
- handleUserActivity() {
- if (this.isRunning && !this.isPaused) {
- this.resetTimer();
- }
- }
- handleVisibilityChange() {
- this.pageVisible = document.visibilityState === 'visible';
-
- if (this.pageVisible && this.isRunning && this.isPaused) {
- this.isPaused = false;
- this.startTime = Date.now() - (this.config.timeout - this.timeLeft);
- this.startTimer();
- } else if (!this.pageVisible && this.isRunning && !this.isPaused) {
- this.isPaused = true;
- this.clearTimer();
- }
- }
- start() {
- if (this.isRunning) return;
-
- this.isRunning = true;
- this.isPaused = false;
- this.warningTriggered = false;
- this.startTime = Date.now();
- this.timeLeft = this.config.timeout;
-
- this.config.onStart();
- this.startTimer();
- }
- startTimer() {
- this.clearTimer();
-
- this.timer = setInterval(() => {
- if (!this.isPaused) {
- const elapsed = Date.now() - this.startTime;
- this.timeLeft = this.config.timeout - elapsed;
-
- if (this.timeLeft <= 0) {
- this.clearTimer();
- this.isRunning = false;
- this.timeLeft = 0;
- this.config.onTimeout();
- } else if (this.timeLeft <= this.config.warningTime && !this.warningTriggered) {
- this.warningTriggered = true;
- this.config.onWarning();
- }
- }
- }, 100);
- }
- resetTimer() {
- this.startTime = Date.now();
- this.timeLeft = this.config.timeout;
- this.warningTriggered = false;
- this.config.onReset();
- }
- reset() {
- if (!this.isRunning) return;
- this.resetTimer();
- }
- stop() {
- if (!this.isRunning) return;
-
- this.clearTimer();
- this.isRunning = false;
- this.isPaused = false;
- this.timeLeft = this.config.timeout;
- this.warningTriggered = false;
- this.config.onStop();
- }
- clearTimer() {
- if (this.timer) {
- clearInterval(this.timer);
- this.timer = null;
- }
- }
- }
|