本文介绍如何在JavaScript中利用onunload事件处理页面关闭时的逻辑。针对onunload在刷新或跳转时也会触发的特性,通过判断window.screenTop或screenLeft的值是否大于特定阈值(如9000)来区分窗口关闭与页面导航。结合Ajax或window.location.href触发后端请求,实现购物车Session在窗口真正关闭时的数据同步与清理。
onunload事件在Session清理中的应用场景
周末回顾之前开发的B2C电商平台时,发现部分功能尚需完善。其中一个关键场景涉及购物车数据的持久化:购物车模型存储在Session中,以便在整个购物流程中随时获取。当用户购买某商品时,数据库中的库存数量会相应扣减。然而,若用户直接关闭浏览器窗口,Session中的购物车数据可能无法及时同步回数据库。为解决此问题,通过搜索引擎查找资料,发现一种常见方案是:在窗口关闭时自动清除或处理Session。具体实现思路是在HTML的<body>标签中绑定onunload属性,例如:<body onunload="close()">。该属性会在窗口关闭时触发close()函数,从而在JS中定义清理Session的逻辑。
onunload触发的局限性及解决方案
然而,实际测试发现该方案存在缺陷:当用户刷新当前页面或点击页面上的链接进行跳转时,onunload事件同样会被触发。这导致非关闭窗口的正常导航操作也会错误地执行Session清理逻辑。因此,需要寻找更精确的方法来区分“窗口关闭”与“页面导航”。
利用screenTop/screenLeft判断窗口关闭
经过进一步检索,找到以下代码示例用于辅助判断:
<script>
window.onunload = function(){if(self.screenTop>9000)alert('该窗口已经被关闭!')}
</script>
或者采用另一种判断方式:
<script>
window.onunload = function(){if(self.screenLeft>9000)alert(该窗口已经被关闭!.')}
</script> 上述代码的原理说明如下:
window.screenTop
用于获取浏览器窗口客户区左上角相对于屏幕左上角的Y坐标值。
判断条件中screenTop后的数值必须大于当前显示分辨率的高度。
例如,若屏幕分辨率为800*600,则该数值需大于600。
window.screenLeft
用于获取浏览器窗口客户区左上角相对于屏幕左上角的X坐标值。
判断条件中screenLeft后的数值必须大于当前显示分辨率的宽度。
例如,若屏幕分辨率为800*600,则该数值需大于800。
在实际应用中,通常将这两个阈值设置为9000,以确保覆盖常见分辨率。
基于上述原理,通过判断screenTop或screenLeft的值,可以确保onunload事件仅在窗口真正被关闭时触发,从而实现了预期的功能。
总结:
结合后端请求实现Session数据同步
具体实现方式包括:① 在onunload属性中,可以使用Ajax异步清除Session,或者通过window.location.href触发特定的后端请求。例如,在使用Struts2框架的项目中,可以编写如下代码:<body onunload="javascript:window.location.href='${pageContext.request.contextPath }/cart/closeWindow.action'">。
此时,closeWindow.action接口负责处理Session中的购物车数据,将未结算的商品数量重新添加回数据库。
② 虽然也可以使用Ajax处理请求,但由于我们仅需清理Session,无需等待异步返回结果,因此采用直接触发HTTP请求的方式更为简洁。最终的完整写法如下:
具体代码实现如下:
<body
onunload="javascript:if(self.screenTop>9000) window.location.href='${pageContext.request.contextPath }/cart/closeWindow.action';">