页面重新可见时如何正确覆盖JavaScript变量值
问题原因
代码不生效是JavaScript函数作用域规则导致的:
你在visibilitychange回调中用var重新声明starts变量时,实际是在回调函数的局部作用域内创建了一个全新的同名变量,和外层$(document).ready作用域下定义的starts完全独立。回调执行完毕后这个局部变量会被销毁,外层AJAX逻辑读取的始终是初始定义的外层starts,永远拿不到更新后的值。
修复方案
去掉事件回调内starts前的var声明关键字,直接对外层已经定义的starts变量赋值即可。
另外建议直接在visibilitychange事件的页面隐藏分支触发上报逻辑,避免页面卸载时AJAX请求被浏览器取消导致数据丢失,完整可运行代码如下:
$(document).ready(function() { var starts = Math.ceil(Date.now() / 1000); document.addEventListener('visibilitychange', function() { if (document.hidden) { // 页面切走/最小化时执行上报 var stayTime = Math.ceil(Date.now() / 1000) - starts; // 替换为实际的AJAX请求逻辑,优先使用navigator.sendBeacon上报可提升成功率 $.ajax({ url: '/your-log-api', type: 'POST', data: {stay_duration: stayTime} }); } else { // 页面重新激活时更新起始时间,不要重复声明变量 starts = Math.ceil(Date.now() / 1000); } }); });
补充说明
- 不要在内部作用域重复用
var/let/const声明和外层同名的变量,否则会触发作用域遮蔽,外层变量无法被修改 - 如果需要统计更精准的页面停留时长,还可以额外监听
pagehide事件作为补充上报时机,覆盖用户直接关闭页面的场景
内容的提问来源于stack exchange,提问作者Hans Martin
相关产品推荐
相关产品推荐

