web游览器的标签页仿 ios mac 苹果的墓碑机制 (js代码)
背景:
本来项目开发系统防挂机功能,在其余游览器中均可以使用。但是呢在苹果的safair游览器中会出现几率失效,最后经过排查发现是苹果的墓碑机制导致。即:此标签页活跃,其他标签页假死。然后就导致防挂机失效了。
原理:
假如当前游览器中有3个标签页分别是A,B,C,每个标签页都有倒计时。正常情况下,每个标签页都会倒计时。但是苹果游览器只会有一个标签页A正常倒计时,其余的B,C 倒计时不生效。
所以就需要仿墓碑机制进行开发。原理如下:
A标签页打开时,B和C标签页不活跃;
当打开其他标签页,ABC处于后台时候,最近操作的一个标签页处于活跃;
核心逻辑代码:
//分钟数
var min;
var timeLeft;
var timer=null;
var IsnewRequest = false;
var StayTimer = null;
function resetTimer() {
backInit();
} function uuid(len, radix) {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
var uuid = [], i;
radix = radix || chars.length; if (len) {
// Compact form
for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
} else {
// rfc4122, version 4 form
var r; // rfc4122 requires these characters
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4'; // Fill in random data. At i==19 set the high bits of clock sequence as
// per rfc4122, sec. 4.1.5
for (i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | Math.random()*16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
} return uuid.join('');
} function GetBigTime() { //判断:如果有其他页面打开,则赋值最大倒计时值,如果< 10 退出
//1,获取所有的time
//2,取最大的时间
//3,如果最大的时间<10 则不管;
var countDownKeyList= [];
var localStorageKeys = Object.keys(localStorage)
for (var i=0;i<localStorageKeys.length;i++) {
var item = localStorageKeys[i];
if(item.indexOf("CountDown")!=-1)
{
countDownKeyList.push(item);
}
} var countDownValueList= [];
for(var i= 0; i<countDownKeyList.length;i++)
{
var value = localStorage.getItem(countDownKeyList[i]);
countDownValueList.push(value);
} //验证最大时间
var bigTime = countDownValueList.sort().reverse()[0];
//if(Number(bigTime)>=3)
if(Number(bigTime)>=3 && Number(bigTime) != 19999999)
{
//取运行中的倒计时最大值;
window.localStorage.setItem(window.CountDown,bigTime);
return false;
}
else
{
window.localStorage.removeItem(window.CountDown);
return true;
} } function ShowCountDown (second){
const s = second % 60;
const m = Math.floor(second / 60);
return `${`00${m}`.slice(-2)} : ${`00${s}`.slice(-2)}`;
}; function reSetTimeoutInit()
{
window.localStorage.setItem("checkClose","1");
setTimeout(function(){
//1秒后执行刷新
window.localStorage.removeItem('checkClose');
}, 1000); //单位是毫秒
setTimeoutInit();
} var IsResetTime = false;
function setTimeoutInit() { this.IsnewRequest = true;
//默认无操作时间为15分钟
min = 15;
let value = window.localStorage.getItem("InvalidTime");
//如果取不到session值 则默认15分钟
if(value!=null && value!=undefined)
{
min = Number(value);
} //清理之前的倒计时
clearInterval(StayTimer); //没有唯一标识,则生成
if(window.CountDown==''||window.CountDown==undefined)
{
window.CountDown = "CountDown"+this.uuid(8,2);
} //设置初始倒计时
var MainTime = min * 60;
window.localStorage.setItem(window.CountDown,MainTime); StayTimer = setInterval(()=>{ var nowTime = window.localStorage.getItem(window.CountDown);
if(nowTime==null||nowTime=="")
{
clearInterval(StayTimer);
return;
}
//获取存储倒计时
timeLeft = Number(nowTime); var localStorageKeys = Object.keys(localStorage)
var labelList = localStorageKeys.filter(x=> x.indexOf("CountDown")!=-1 );
var activeCount = 0;
for(var i= 0; i<labelList.length;i++)
{
var value = localStorage.getItem(labelList[i]);
var nValue = Number.parseInt(value);
if(nValue!=19999999)
{
activeCount++;
}
} var localStorageKeys = Object.keys(localStorage)
var labelList = localStorageKeys.filter(x=> x.indexOf("CountDown")!=-1 );
var activeCount = 0;
for(var i= 0; i<labelList.length;i++)
{
var value = localStorage.getItem(labelList[i]);
var nValue = Number.parseInt(value);
if(nValue!=19999999)
{
activeCount++;
}
}
//如果没有一个活跃,则重新读取
if(activeCount==0)
{
this.IsnewRequest = true;
} if(this.IsnewRequest==true)
{
this.IsnewRequest = false;
for(var i= 0; i<labelList.length;i++)
{
if(labelList[i]!=window.CountDown)
{
var value = localStorage.getItem(labelList[i])
localStorage.setItem(labelList[i],"19999999");
}
else
{
timeLeft = MainTime;//设置的默认值
localStorage.setItem(labelList[i],MainTime);
}
}
} if (document.hidden) {
//首先重置时间
//赋值其余的为-999
if(timeLeft==19999999)
{
IsResetTime = true
const show = ShowCountDown(timeLeft);//恢复倒计时 并且重置时间;
console.log("[时停],倒计时:"+timeLeft);
}
else
{
if(IsResetTime)
{
timeLeft = MainTime;//设置的默认值
IsResetTime = false;
}
const show = ShowCountDown(timeLeft--);//恢复倒计时 并且重置时间;
console.log("[独苗],倒计时:"+timeLeft);
}
} else {
//首先重置时间
//赋值其余的为-999
if(timeLeft==19999999)
{
IsResetTime = true
const show = ShowCountDown(timeLeft);//恢复倒计时 并且重置时间;
console.log("[时停],倒计时:"+timeLeft);
}
else
{
if(IsResetTime)
{
timeLeft = MainTime;//设置的默认值
IsResetTime = false;
}
const show = ShowCountDown(timeLeft--);//恢复倒计时 并且重置时间;
console.log("[独苗],倒计时:"+timeLeft);
}
} var checkShow = window.localStorage.getItem('checkShow');
var blCheckShow =Number(checkShow);
if(blCheckShow==1)
{
timeLeft = -1;
setTimeout(function(){
//1秒后执行刷新
window.localStorage.removeItem('checkShow');
}, 1000); //单位是毫秒
} //const show = ShowCountDown(timeLeft--);
//设置倒计时
window.localStorage.setItem(window.CountDown,timeLeft);
if (timeLeft < 0)
{
//#endregion
window.localStorage.setItem('checkShow',"1");
var IsResetTime = false;
var blresult = this.GetBigTime();
if(blresult==true)
{
//清理定时
clearInterval(StayTimer);
//业务操作:
document.getElementsByClassName("fullScreenDiv")[0].style.display = "block";
document.getElementsByClassName("promptDiv")[0].style.display = "block";
startCountDown($("#spanCountDown").text()); } } },1000); //countTime(); var vdoc = document.getElementById("ScormIframe").contentDocument; if (vdoc != null) {
vdoc.addEventListener("mousemove", resetTimer, false);
vdoc.addEventListener("mousedown", resetTimer, false);
vdoc.addEventListener("keypress", resetTimer, false);
vdoc.addEventListener("DOMMouseScroll", resetTimer, false);
vdoc.addEventListener("mousewheel", resetTimer, false);
vdoc.addEventListener("touchmove", resetTimer, false);
vdoc.addEventListener("MSPointerMove", resetTimer, false);
}
else{
} if (language == "zh-CN") {
$("#msgInfo").html("由于长时间未操作,课件将在倒计时结束后自动关闭,系统会保存您的学习记录。");
$("#msgTimeout").html("如果您想继续学习,请关闭此窗口。");
}
else {
$("#msgInfo").html("Since there is no operation for a period of time, the courseware will be closed automatically at the end of the countdown and the learning record will be saved.");
$("#msgTimeout").html("If you want to continue learning, just close this window.");
}
} function countTime() {
if (timeLeft == 0) {
document.getElementsByClassName("fullScreenDiv")[0].style.display = "block";
document.getElementsByClassName("promptDiv")[0].style.display = "block";
startCountDown($("#spanCountDown").text());
} var startMinutes = parseInt(timeLeft / (60 * 1000), 10);
var startSec = parseInt((timeLeft - startMinutes * 60 * 1000) / 1000)
timeLeft = timeLeft - 1000;
setTimeout('countTime()', 1000);
//console.log(timeLeft);
} function startCountDown(html){
clearInterval(this.CountDownTimer);
this.CountDownTimer = setInterval(() => { var checkClose = window.localStorage.getItem('checkClose');
var blCheckClose =Number(checkClose);
if(blCheckClose==1)
{
// $("#spanCountDown").text(60);
// clearInterval(this.CountDownTimer);
document.getElementsByClassName("fullScreenDiv")[0].style.display = "none";
document.getElementsByClassName("promptDiv")[0].style.display = "none";
setTimeoutInit();
setTimeout(function(){
//1秒后执行刷新
window.localStorage.removeItem('checkClose');
}, 1000); //单位是毫秒
}
else
{
html = parseInt(html) - 1;
if (parseInt(html) <= 0) {
closeme();
}
$("#spanCountDown").text(html);
}
////console.log($("#spanCountDown").text());
}, 1000);
}
function closeme() {
var browserName = navigator.appName;
if (browserName == "Netscape") {
window.open('', '_parent', '');
window.close();
} else if (browserName == "Microsoft Internet Explorer") {
window.opener = "whocares";
window.close();
}
} function backInit() { reSetTimeoutInit(); // min = 15;
// timeLeft = min * 60 * 1000;
$("#spanCountDown").text(60);
clearInterval(this.CountDownTimer);
document.getElementsByClassName("fullScreenDiv")[0].style.display = "none";
document.getElementsByClassName("promptDiv")[0].style.display = "none";
}
结语:
其实就是按照墓碑机制进行仿照开发,此文章进行记录以后可以在其他平台进行此机制的开发;
web游览器的标签页仿 ios mac 苹果的墓碑机制 (js代码)的更多相关文章
- web自动化测试—selenium操作游览器属性
# coding=utf-8'''web游览器属性: 页面最大化 maximize_window() 获取当前页面地址 current_url 代码 page_source title title 后 ...
- web前端之 HTML标签详细介绍
html标签的分类 点我查看完整的html标签介绍 在html中,标签一般分为块级标签和行内标签 块级标签:块元素一般都从新行开始,它可以容纳内联元素和其他块元素,常见块元素是段落标签"p& ...
- 标签页(tab)切换的原生js,jquery和bootstrap实现
概述 这是我在学习课程Tab选项卡切换效果时做的总结和练手. 原课程中只有原生js实现,jquery和bootstrap实现是我自己补上的. 本节内容 标签页(tab)切换的原生js实现 标签页(ta ...
- 【vue】vue中实现标签页
前言 tab标签页实现很多, 纯css实现, js实现等, 外加一些特殊动画. vue中实现标签页实现 keep-alive标签和is特性 vue-router中嵌套路由 is特性实现(推荐) 优点: ...
- 【Winform-自定义控件】自定义Tab Control 带关闭符号(X)的标签页
a form & a tabControl 思路: DrawMode设一定要设为OwnerDrawFixed 事件:Form_Load.tabControl1_DrawItem.tabCont ...
- Web编程基础--HTML、CSS、JavaScript 学习之课程作业“仿360极速浏览器新标签页”
Web编程基础--HTML.CSS.JavaScript 学习之课程作业"仿360极速浏览器新标签页" 背景: 作为一个中专网站建设出身,之前总是做静态的HTML+CSS+DIV没 ...
- 阻止iOS Web APP中点击链接跳转到Safari 浏览器新标签页
问题:ios封装完之后,点击里边的按钮会跳转到网页上 ——小卡遇到这个问题就是这样解决的↓↓↓ 解决方法:建议将代码放到</head>标签前,当然,另外存为一个js 文件引用也是可以的呦~ ...
- IOS UIScrollView + UIButton 实现segemet页面和顶部标签页水平滚动效果
很长一段时间没有写博客了,最近在学习iOS开发,看了不少的代码,自己用UIScrollView和UIButton实现了水平滚动的效果,有点类似于今日头条的主界面框架,效果如下: 代码如下: MyScr ...
- Atitit.web 视频播放器classid clsid 大总结quicktime,vlc 1. Classid的用处。用来指定播放器 1 2. <object> 标签用于包含对象,比如图像、音
Atitit.web 视频播放器classid clsid 大总结quicktime,vlc 1. Classid的用处.用来指定播放器 1 2. <object> 标签用于包含对象,比如 ...
- mac系统升级导致无法在iOS设备中运行Safari Web 调试器
macOS系统升级之后,可能会导致Safari开发选项中没有iOS设备,进而无法运行Safari Web 调试器. 此问题的解决办法: 请转到设置>常规>重置>重置位置和隐私.现在, ...
随机推荐
- 如何快速实现Prometheus监控Kubernetes集群
Prometheus K8S集群中常见的监控工具有哪些: Kubernetes Dashboard Kube-monkey K8s-testsuite Kubespray Minikube Prome ...
- gensim的word2vec的简单使用
from gensim.models import Word2Vec as wtv import jieba s1 = "刘新宇是一个自然语言处理算法工程师" s2 = " ...
- 为什么序列化要实现Serializable接口
为什么实现了Serializable接口就会序列化? 实现了Java中的Serializable接口的类会被称为可序列化的,这意味着它们的实例可以被序列化为字节流,以便于在网络上传输.保存到文件中或者 ...
- Borůvka MST算法
当我认为最MST(最小生成树)已经没有什么学的了,才发现世界上还有个这个kruskal和prim结合的玩意 Borůvka 运用并查集的思想,先将每一个初始点集初始化为有且只有自己的点集,然后每一次合 ...
- 力扣610(MySQL)-判断三角形(简单)
题目: 表: Triangle 写一个SQL查询,每三个线段报告它们是否可以形成一个三角形. 以 任意顺序 返回结果表. 查询结果格式如下所示. 示例1: 解题思路: 判断是否形成三角形的准则是:两 ...
- HarmonyOS NEXT应用开发之预加载so并读取RawFile文件
介绍 本示例主要介绍在TaskPool子线程中使用 dlopen 预加载 so 库并使用句柄调用库函数的方法,以及在Native中使用 pread 系统函数读取Rawfile文件的部分文本内容,并添加 ...
- 融合数据库生态:利用 EventBridge 构建 CDC 应用
简介: 近期,EventBridge 事件流已经支持了基于阿里云 DTS服务的 CDC 能力.本文将从 CDC.CDC 在 EventBridge 上的应用以及若干最佳实践场景等方面,为大家介绍如何利 ...
- 万字长文总结与剖析C语言关键字 -- <<C语言深度解剖>>
C总结与剖析:关键字篇 -- <<C语言深度解剖>> 目录 C总结与剖析:关键字篇 -- <<C语言深度解剖>> 程序的本质:二进制文件 变量 1.变量 ...
- jqGrid--设置单元格字体颜色
colModel: [ { name: '列名称', index: '列名称', width: 65, sortable: true, resizable: false, cellattr: addC ...
- 🎉 Socket.D v2.4.12 发布(新增 python 实现)
Socket.D 协议? Socket.D 是一个网络应用协议.在微服务.移动应用.物联网等场景,可替代 http.websocket 等.协议详情参考<官网介绍>. 支持: tcp, u ...