如何可靠地Polyfill `navigator.userActivation.hasBeenActive`属性?
直接上实现代码,这个方案基于真实用户交互事件的isTrusted属性判断,能避开JS模拟的事件,满足你的健壮性需求(无需防范恶意绕过):
if (!navigator.userActivation) { let hasBeenActive = false; let isActive = false; // 定义触发用户激活的事件类型 const activationEvents = ['click', 'keydown', 'touchend', 'pointerup']; const handleActivation = (e) => { if (e.isTrusted) { hasBeenActive = true; isActive = true; // 模拟原生激活状态的超时逻辑(可选) clearTimeout(window._activationTimeout); window._activationTimeout = setTimeout(() => { isActive = false; }, 5000); // 5秒超时可按需调整 } }; // 为每个激活事件添加监听 activationEvents.forEach(event => { window.addEventListener(event, handleActivation, { capture: true }); }); // 挂载polyfill到navigator对象 Object.defineProperty(navigator, 'userActivation', { get: () => ({ get hasBeenActive() { return hasBeenActive; }, get isActive() { return isActive; } }) }); }
关键说明
- 依赖
isTrusted属性:真实用户操作触发的事件该属性为true,JS代码模拟的事件为false,彻底解决你之前click事件不可靠的问题。 - 覆盖多场景交互:除点击外,还包含键盘、触摸、指针事件,和原生
userActivation的触发逻辑对齐。 - 模拟激活状态超时:原生
isActive会在用户交互后短时间内失效,这里设置5秒超时,可根据需求调整时长。 - 不处理恶意绕过:按照你的要求,没有额外添加防范篡改状态的逻辑,保持代码简洁。
使用方式
在项目初始化阶段引入这段代码即可,之后就能像使用原生API一样访问navigator.userActivation.hasBeenActive和navigator.userActivation.isActive。
内容的提问来源于stack exchange,提问作者joe
相关产品推荐
相关产品推荐

