超时失效调查
@[IE11,JavaScript,jQuery Plugin]
业务背景介绍
自助设备的操作状态主要可分为Active(活跃) 和 Idle(闲置) 两种状态:
Active:设备处于活跃状态是正常操作状态,不需要干涉用户行为
Idle:设备闲置时,自助设备需及时知晓: 若业务场景中涉及用户隐私或信息安全,要能够及时退出系统。若停留在首页用户未操作,检测到闲置状态时显示广告轮播图
jQuery idle插件介绍
A dead simple jQuery plugin that executes a callback function if the user is idle.
一个简单的jQuery插件,如果用户空闲时执行回调函数。
GitHub主页
问题描述
在实际项目实施中使用了jQuery idle 插件来监控设备状态,但是经过长期使用发现:
- 在IE11上超时会不定期失效,但是在Chrome上面不会失效
- 一开始超时失效可以通过重置IE浏览器解决;但是重置一段时间后超时依然会失效(后续运维中发现,浏览器重置已经无法解决超时失效问题)
因此这个问题应该与IE11浏览器有关
解决过程:
阅读jQuery 源代码,寻找更多线索
$.fn.idle = function (options) {
var defaults = {
idle: 60000, //idle time in ms
events: 'mousemove keydown mousedown touchstart', //events that will trigger the idle resetter
onIdle: function () {}, //callback function to be executed after idle time
onActive: function () {}, //callback function to be executed after back from idleness
onHide: function () {}, //callback function to be executed when window is hidden
onShow: function () {}, //callback function to be executed when window is visible
keepTracking: true, //set it to false if you want to track only the first time
startAtIdle: false,
recurIdleCall: false
},
idle = options.startAtIdle || false,
visible = !options.startAtIdle || true,
settings = $.extend({}, defaults, options),
lastId = null,
resetTimeout,
timeout;
从源代码可以看到jQuery idle默认检测4个事件 mousemove,keydown ,mousedown ,touchstart
Q: 如果到了本来应该回调Idle逻辑的时间,却没有调用,难道是一直在产生事件触发Active?
A: 于是在active回调方法里增加了log,可以发现:过了一段时间后,IE11中确实又再调用了active的方法
Q: 那是产生了什么事件,导致达到固定时间,idle不会触发呢?
写了一个最简单的测试代码来验证这个问题:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="jquery-3.2.1.js"></script>
<script type="text/javascript">
$(document).mousemove(function(e) {
var date = new Date;
var seconds = date.getSeconds();
var minutes = date.getMinutes();
var hour = date.getHours();
var milliSeconds = date.getMilliseconds();
console.log(hour + ':' + minutes + ':' +seconds + ':' +milliSeconds + ' ' + e.type + ' is fired');
});
$(document).mousedown(function(e) {
var date = new Date;
var seconds = date.getSeconds();
var minutes = date.getMinutes();
var hour = date.getHours();
var milliSeconds = date.getMilliseconds();
console.log(hour + ':' + minutes + ':' +seconds + ':' +milliSeconds + ' ' + e.type + ' is fired');
});
</script>
<title></title>
</head>
<body>
<p>This is a mouseMove event detect Page</p>
</body>
</html>
测试过程中,拔掉鼠标,但是让鼠标聚焦浏览器页面,
测试结果
A: 结果发现,即使拔掉鼠标,2秒左右以后,浏览器又再次产生了mosemove 事件
Q: 那为什么IE11会自己产生mosemove事件呢?在stackoverflow上提了这个问题,并提供了测试代码
https://stackoverflow.com/q/50225271/5426223?sfb=2
但是几个老外都表示测试后没发现IE11有这样的问题,其中一个还说坐了一个小时都没发现有mosemove事件
网友评论