You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Idle Timer问题:视频播放活动被误判为用户闲置

问题

在React应用中使用react-idle-timer追踪用户闲置状态时,遇到视频播放被判定为闲置的问题。应用内包含视频播放器组件,即便视频正在播放,react-idle-timer仍会触发闲置状态,不符合需求。已尝试监听视频的play、pause、seek等交互事件,但问题依旧。需要找到能区分真实用户闲置与视频播放活动的方案,或是react-idle-timer的特定配置/变通方法。

用户相关代码:

const handleOnIdle = () => {
    console.log('user is idle')
    console.log('last active', getLastActiveTime())
    authService.logout();
}

const handleOnActive = (event) => {
    console.log('user is active', event)
    console.log('time remaining', getRemainingTime())
}

const handleOnAction = (event) => {
    console.log('User still active', event)
}

const { getRemainingTime, getLastActiveTime } = useIdleTimer({
    timeout: 10000,
    onIdle: handleOnIdle,
    onActive: handleOnActive,
    onAction: handleOnAction,
    debounce: 500
})

解决方案

1. 视频播放期间手动重置IdleTimer

在视频播放的生命周期事件(比如timeupdate)中手动调用reset()方法,告知react-idle-timer用户仍处于活跃状态:

const videoRef = useRef(null);
const { getRemainingTime, getLastActiveTime, reset } = useIdleTimer({
    timeout: 10000,
    onIdle: handleOnIdle,
    onActive: handleOnActive,
    onAction: handleOnAction,
    debounce: 500
});

useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    // 视频播放时触发重置
    const handleTimeUpdate = () => reset();
    video.addEventListener('timeupdate', handleTimeUpdate);

    return () => {
        video.removeEventListener('timeupdate', handleTimeUpdate);
    };
}, [reset]);

若担心timeupdate频繁触发影响性能,可添加节流控制:

import { throttle } from 'lodash';

const throttledReset = throttle(reset, 2000);
const handleTimeUpdate = () => throttledReset();

2. 自定义闲置判定逻辑,忽略视频播放状态

维护一个标志位标记视频是否在播放,在onIdle回调中先校验这个标志,再执行闲置操作:

const [isVideoPlaying, setIsVideoPlaying] = useState(false);
const videoRef = useRef(null);

const { getRemainingTime, getLastActiveTime } = useIdleTimer({
    timeout: 10000,
    onIdle: () => {
        // 视频播放时跳过闲置逻辑
        if (isVideoPlaying) return;
        console.log('user is idle')
        console.log('last active', getLastActiveTime())
        authService.logout();
    },
    onActive: handleOnActive,
    onAction: handleOnAction,
    debounce: 500
});

useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    const handlePlay = () => setIsVideoPlaying(true);
    const handlePause = () => setIsVideoPlaying(false);

    video.addEventListener('play', handlePlay);
    video.addEventListener('pause', handlePause);
    video.addEventListener('ended', handlePause);

    return () => {
        video.removeEventListener('play', handlePlay);
        video.removeEventListener('pause', handlePause);
        video.removeEventListener('ended', handlePause);
    };
}, []);

这种方式无需频繁重置计时器,仅在闲置触发时做判断,性能开销更低。

3. 扩展react-idle-timer的监听事件列表

默认情况下,react-idle-timer只监听鼠标、键盘等用户交互事件,可将视频相关的用户主动操作事件加入监听列表,让这些动作被识别为用户活跃:

const { getRemainingTime, getLastActiveTime } = useIdleTimer({
    timeout: 10000,
    onIdle: handleOnIdle,
    onActive: handleOnActive,
    onAction: handleOnAction,
    debounce: 500,
    // 添加视频交互事件
    events: [
        'mousedown', 'mousemove', 'keydown', 'scroll', 'touchstart',
        'play', 'pause', 'seeked', 'volumechange'
    ]
});

注意:该方法仅对用户主动触发的视频事件有效,视频自动播放的timeupdate不会被识别,若需覆盖自动播放场景,建议结合第一种方法使用。

内容的提问来源于stack exchange,提问作者AlgoPro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 13:52:58