如何在React视频播放器中实现视频播放时自动随机弹出人机验证弹窗
刚巧我之前做过类似的React视频播放器验证需求,给你整理了一套完整的实现方案,涵盖随机触发、模态框控制和视频状态同步这些核心点,直接就能上手用。
整体实现思路
核心逻辑就是:监听视频播放事件→在播放过程中生成随机时间点→到点后暂停视频并弹出验证码模态框→验证通过后恢复视频播放,同时做好定时器清理避免内存泄漏。
核心实现步骤&代码示例
1. 基础组件结构
我们用React函数组件来实现,用到useRef获取视频元素引用,useState控制模态框显示,useEffect处理事件监听和定时器清理。
import { useState, useRef, useEffect } from 'react'; const VideoPlayerWithCaptcha = () => { // 控制验证码模态框显示/隐藏 const [showCaptchaModal, setShowCaptchaModal] = useState(false); // 视频元素引用 const videoRef = useRef(null); // 存储定时器ID,用于后续清理 const timerRef = useRef(null); // 生成随机触发时间:取视频时长的10%~80%区间,避免开头或结尾弹出 const getRandomTriggerTime = (videoDuration) => { const min = videoDuration * 0.1; const max = videoDuration * 0.8; return Math.floor(Math.random() * (max - min + 1)) + min; }; // 启动随机验证定时器:视频加载完成后获取时长,设置定时触发 const startCaptchaTimer = () => { const video = videoRef.current; if (!video) return; // 等待视频元数据加载完成,确保能拿到正确时长 video.onloadedmetadata = () => { const triggerTime = getRandomTriggerTime(video.duration); timerRef.current = setTimeout(() => { video.pause(); // 暂停视频 setShowCaptchaModal(true); // 弹出验证码模态框 }, triggerTime * 1000); // 转成毫秒单位 }; }; // 处理验证码验证通过逻辑 const handleCaptchaVerify = () => { setShowCaptchaModal(false); videoRef.current?.play(); // 恢复视频播放 // 可选:如果不想同一播放周期内重复弹出,可以添加状态标记 // setIsVerified(true); }; // 监听视频播放事件,启动定时器;组件卸载时清理监听和定时器 useEffect(() => { const video = videoRef.current; if (!video) return; video.addEventListener('play', startCaptchaTimer); return () => { video.removeEventListener('play', startCaptchaTimer); if (timerRef.current) clearTimeout(timerRef.current); }; }, []); return ( <div className="video-player-container"> {/* 视频播放器 */} <video ref={videoRef} src="your-video-url.mp4" // 替换成你的视频地址 controls style={{ width: '100%', maxWidth: '800px' }} /> {/* 验证码模态框 */} {showCaptchaModal && ( <div className="captcha-modal-overlay"> <div className="captcha-modal"> <h3>请完成人机验证</h3> <p>点击下方按钮确认您不是机器人</p> <button onClick={handleCaptchaVerify} className="verify-btn"> 我不是机器人 </button> </div> </div> )} {/* 内置样式,也可以提取到外部CSS文件 */} <style jsx>{` .video-player-container { position: relative; max-width: 800px; margin: 0 auto; } .captcha-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); display: flex; justify-content: center; align-items: center; z-index: 1000; } .captcha-modal { background: #fff; padding: 2.5rem; border-radius: 10px; box-shadow: 0 0 20px rgba(0,0,0,0.3); text-align: center; } .verify-btn { margin-top: 1.5rem; padding: 1rem 2rem; background-color: #2563eb; color: #fff; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; transition: background-color 0.2s; } .verify-btn:hover { background-color: #1d4ed8; } `}</style> </div> ); }; export default VideoPlayerWithCaptcha;
2. 关键细节说明
- 验证码替换:示例里的按钮是模拟验证,实际项目中可以替换成Google reCAPTCHA或其他第三方验证码服务,只需要把
handleCaptchaVerify改成第三方验证的成功回调即可。 - 避免重复触发:如果不想同一视频播放周期内多次弹出验证,可以添加一个
isVerified状态,验证通过后标记为true,后续不再启动定时器。 - 视频加载容错:必须等待
onloadedmetadata事件触发后再获取视频时长,否则video.duration会返回NaN,导致随机时间生成失败。 - 内存泄漏防范:组件卸载或视频暂停时一定要清理定时器和事件监听,避免内存泄漏问题。
- 移动端适配:模态框的样式已经做了基础适配,确保在移动端也能正常显示和点击。
内容的提问来源于stack exchange,提问作者Xena
相关产品推荐
相关产品推荐

