首页 > 其他分享 >[js] 页面可见性API 监测用户切屏

[js] 页面可见性API 监测用户切屏

时间:2024-08-30 22:50:45浏览次数:3  
标签:function visibilityState js visible API 切屏 document 考试 页面

Page Visibility API

在做考试系统或者网课系统的时候,通常需要监测用户是否隐藏了当前标签页在看其它页面。

Page Visibility API提供了一个事件和两个状态来监测页面可见性,可以用它来判断用户是否切屏。

visibilitychange

这个事件会在页面可见性变化时触发。(隐藏时、打开时)

// 使用 addEventLisitener
document.addEventListener('visibilitychange', (e)=>{
    console.log('visibilityState: ', document.visibilityState);
});

// 或者 onvisibilitychange
document.onvisibilitychange = function(){
    console.log('visibilityState: ', document.visibilityState);
}

document.visibilityState

这个变量有3种值:

  • hidden

    • 浏览器被最小化了;
    • 浏览器打开,但是当前看的是其它标签页;
    • 这个标签页要被卸载了(unload);
  • visible

    • 当前正在看标签页;

    • 当前浏览器处于最小化,但是正在预览页面内容;

      如下图,这种把鼠标移到任务栏图标上的行为也会触发 visibilitychange 事件,且 document.visibilityState 变为 visible。

      image-20240830191250009
  • prerender:页面即将或正在渲染,处于不可见状态。

document.hidden

这个状态仅用于兼容,平时应使用document.visibilityState。当document.visibilityStatevisible时,document.hiddenfalse,其余情况下都为 true

iframe

当页面中通过 iframe 嵌入子文档时,iframe节点的display:none;并不会触发子文档的 visibilitychange事件。

子文档的可见性和父文档的可见性保持一致。

示例场景

考试违规切屏次数统计

let violationCount = 0;
const maxViolations = 3; // 设定最大违规次数

document.addEventListener('visibilitychange', function() {
    if (document.visibilityState === 'visible') {
        console.log('考试页面重新可见');
    } else {
        violationCount++;
        console.log(`考试页面不可见,违规次数: ${violationCount}`);

        // 如果违规次数达到上限,触发结束考试的逻辑
        if (violationCount >= maxViolations) {
            endExam();
        } else {
            alert(`警告:请勿离开考试页面!您已违规 ${violationCount} 次,最多允许 ${maxViolations} 次违规。`);
        }
    }
});

function endExam() {
    alert('您已多次离开考试页面,考试结束!');
    // 在此添加结束考试的逻辑,例如提交答案并退出考试界面
    submitExam();
}

function submitExam() {
    // 模拟提交考试结果
    console.log('考试结果已提交');
    // 重定向到考试结束页面或显示结束信息
    window.location.href = '/exam-finished';
}

// 模拟考试开始
console.log('考试开始,请勿离开页面。');

"被动"网课学习

document.addEventListener('visibilitychange', function() {
    if (document.visibilityState === 'visible') {
        video.play();	// 视频播放
    } else {
        video.pause();	// 视频暂停
    }
});

如何避免逃课?

下面的策略可以提高逃课的门槛(用户可能会编写脚本来让视频在页面不可见的情况下也能播放),但是只能说是防君子不防小人。

  1. setInterval定时检查visibilityState,缺点是定时器在页面不可见的情况下执行频率和设定的时间可能不一样。

    const videoElement = document.querySelector('video');
    
    function checkVisibility() {
        if (document.visibilityState === 'visible') {
            if (videoElement.paused) {
                videoElement.play(); // 播放
            }
        } else {
            if (!videoElement.paused) {
                videoElement.pause(); // 暂停
            }
        }
    }
    
    // 初始检查页面可见性并启动定时器
    checkVisibility();
    setInterval(checkVisibility, 1000); // 每秒检查一次页面可见性
    
  2. 监听视频元素的play事件,视频开始播放的时候visibilityState应为visible,否则暂停播放。

    video.addEventListener('play', function() {
        if (document.visibilityState !== 'visible') {
            videoElement.pause();	// 视频暂停
        }
    });
    
  3. 冻结相关的属性和方法,避免用户重写。

    Object.defineProperty(document, 'visibilityState', {
        configurable: false,
        enumerable: true,
        writable: false,
        value: document.visibilityState
    });
    
    Object.defineProperty(document, 'hidden', {
        configurable: false,
        enumerable: true,
        writable: false,
        value: document.hidden
    });
    

标签:function,visibilityState,js,visible,API,切屏,document,考试,页面
From: https://www.cnblogs.com/feixianxing/p/18389603/javascript-page-visibility-api-detect-page-

相关文章

  • [js] 页面可见性API 监测用户切屏
    PageVisibilityAPI在做考试系统或者网课系统的时候,通常需要监测用户是否隐藏了当前标签页在看其它页面。PageVisibilityAPI提供了一个事件和两个状态来监测页面可见性,可以用它来判断用户是否切屏。visibilitychange这个事件会在页面可见性变化时触发。(隐藏时、打开时)//......
  • [js] 页面可见性API 监测用户切屏
    PageVisibilityAPI在做考试系统或者网课系统的时候,通常需要监测用户是否隐藏了当前标签页在看其它页面。PageVisibilityAPI提供了一个事件和两个状态来监测页面可见性,可以用它来判断用户是否切屏。visibilitychange这个事件会在页面可见性变化时触发。(隐藏时、打开时)//......
  • python的py文件 如何在window和linux系统中 使用命令的方式执行 接收json参数 两者的
    1.在Python中,可以使用内置的sys模块来在Windows和Linux系统中接收命令行参数。使用sys.argv,它是一个列表,包含命令行参数。sys.argv[0]是脚本名,其余元素是命令行参数。示例代码:importsys#检查参数个数iflen(sys.argv)<2:print("请提供至少一个参数。")sys.......
  • JS如何实现深拷贝
    目录js实现深拷贝js中的浅拷贝方法object.assign()拓展运算符js中深拷贝的原理和实现手写实现深拷贝手写实现深拷贝改进版js实现深拷贝自己创建一个新的对象,来接收你要重新复制或引用的对象值。如果对象属性是基本的数据类型,复制的就是基本类型的值给新对象;但如果......
  • [js] 页面可见性API 监测用户切屏
    PageVisibilityAPI在做考试系统或者网课系统的时候,通常需要监测用户是否隐藏了当前标签页在看其它页面。PageVisibilityAPI提供了一个事件和两个状态来监测页面可见性,可以用它来判断用户是否切屏。visibilitychange这个事件会在页面可见性变化时触发。(隐藏时、打开时)//......
  • Threejs路径规划案例V1
       最近在做一个路径规划的例子,大概场景是在一个xy坐标系中,有几个障碍物,一个车要绕过这些障碍物到达目的地,本来用java来实现,但是java调试太不直观了,我就想起用threejs把场景简单搭建出来,规划好的路线也直接展示出来,就可以实时查看路径规划的怎么样了。先来一张效果图:首先是添加t......
  • 计算机毕业设计express+Node.js+vue毕业生交流学习平台g1el1
    设计框架:Vue1.   表现层:写多个vue页面,负责接收用户请求数据和处理后的结果显示2.   控制器层:又多个控制器组成,这些控制器用于拦截用户请求,并调用业务逻辑组件的业务逻辑方法,并处理用户请求,根据不同的处理结果发送到相应的表现层组件3.   业务逻辑层:由实现所需业......
  • JS小案例:单个按钮绑定时钟开启和暂停以及随机点名
     单个按钮开启暂停时钟案例单个按钮绑定时钟案例中,核心在于进行value值的判断,每次点击按钮都会进行一次value值判断以及value值更改HTML源码:<!DOCTYPEhtml><html> <head> <metacharset="utf-8"> <title>一个按钮绑定时钟开始和暂停</title> </head> <bodyonlo......
  • 欧洲各国家天气预报接口对接,可预报15日天气api
    接口说明地图上有的城市都可以返回天气数据,支持20余种语言。包含基本天气信息、湿度、能见度、气压、降雨概率、日出日落、月初月落、空气质量指数、主要污染物等,可按地名、IP、经纬度坐标查询。对接准备请先注册账号获取appid和appsecret,可以免费测试,测试后需要购......
  • JS逆向入门案例-xx志愿服务网encData-05
    文章目录概要整体架构流程技术细节小结概要提示:仅供学习,不得用做商业交易,如有侵权请及时联系!逆向:xx志愿服务网URL:aHR0cDovL2NoaW5hdm9sdW50ZWVyLm1jYS5nb3YuY24vc2l0ZS9wcm9qZWN0目标:表单数据中的encData参数整体架构流程提示:分析-调试-猜想-实现-执......