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 调试器. 此问题的解决办法: 请转到设置>常规>重置>重置位置和隐私.现在, ...
随机推荐
- 【GDKOI 2024 TG Day2】染色(set) 题解
发现我们给一个点染上色后有: 我们称这是一个大小为 1 的十字. 进一步地,我们给这 5 个点再次染上色后有: 我们称这是一个大小为 2 的十字. 同理可得,我们给这 5 个点染上相同的大小为 2 的 ...
- dva使用yarn编译出错
1. 报错信息 ./src/models/example.jsModule build failed: TypeError: /Users/user/Desktop/learn-code/10.Rea ...
- 很强!4.7k star,推荐一款Python工具,可实现自动化操作!!
1.介绍 在日常工作中,肯定会遇到一些重复性的工作,不管是点击某个按钮.写东西,打印东西,还是复制粘贴拷贝资料之类的,需要进行大量的重复操作.按键精灵大家都听说过,传统的方式,大家可以使用按键精灵将操 ...
- 力扣1097(MySQL)-游戏玩法分析Ⅴ(困难)
题目: 我们将玩家的安装日期定义为该玩家的第一个登录日. 我们还将某个日期 X 的第 1 天留存时间定义为安装日期为 X 的玩家的数量,他们在 X 之后的一天重新登录,除以安装日期为 X 的玩家的数量 ...
- 力扣443(java)-压缩字符串(中等)
题目: 给你一个字符数组 chars ,请使用下述算法压缩: 从一个空字符串 s 开始.对于 chars 中的每组 连续重复字符 : 如果这一组长度为 1 ,则将字符追加到 s 中.否则,需要向 s ...
- 动态尺寸模型优化实践之Shape Constraint IR Part I
简介: 在本系列分享中我们将介绍BladeDISC在动态shape语义下做性能优化的一些实践和思考.本次分享的是我们最近开展的有关shape constraint IR的工作,Part I 中我们将介 ...
- 从KPI到OKR,高阶产品人如何推动业务高速增长
简介: 不管是核心大目标,还是O(Objectives),或者北极星指标,奇妙等式等等,最后都需要核心组织协同方式来推动整个目标聚焦以及过程的落地. 作为产品经理人,相信很多人都遇到过以下的灵魂拷问: ...
- 从 Uno Platform 4 更新 Uno Platform 5 的迁移方法
本文记录我的一个小项目从 Uno Platform 4 更新 Uno Platform 5 的一些变更和迁移方法,由于项目太小,可能踩到的坑不多 官方文档: Migrating to Uno Plat ...
- ESP32 + IDF + LED
一.开发板 ESP32-S3-DevKitC-1 管脚布局 由于这个程序控制比较简单,就不赘述了,直接看程序. 二.程序 #include "freertos/FreeRTOS.h" ...
- 001_Cadence软件的安装与介绍
001_Cadence软件的安装与介绍 软件版本16.6,软件下载:搜索PCB联盟; 安装步骤: 1) 把5个分卷的压缩包解压到同一文件夹; 2) 双击Setup.exe开始安装,先安装Lic ...