我最近在网上研究这个问题,答案总是“不行”,你无法确定用户是留下还是离开(除非用户离开,你的应用程序就停止工作了)。我讨厌“不行”的答案。我想出了以下实用工具。
var OnBeforeUnload = (function(){
var
FDUM = new Function,
AFFIRM = function(){ return true; };
var _reg = function(msg,opts){
opts = opts || {};
var
pid = null,
pre = typeof opts.prefire == 'function' ? opts.prefire : FDUM,
callback = typeof opts.callback == 'function' ? opts.callback : FDUM,
condition = typeof opts.condition == 'function' ? opts.condition : AFFIRM;
window.onbeforeunload = function(){
return condition() ? (pre(),setTimeout(function(){ pid = setTimeout(callback,20); },1),msg) : void 0;
}
window.onunload = function(){ clearTimeout(pid); };
}
var _unreg = function(){ window.onbeforeunload = null; }
return {
register : _reg,
unregister : _unreg
};
})();
所以,例如这样的调用:
OnBeforeUnload.register('Hello!',{
condition:function_that_returns_true_to_fire_event_false_to_ignore,
prefire:function_to_call_on_page_exit_attempt,
callback:function_to_call_if_user_stays
});
处理程序内将调用该条件来确定是否应该激活。如果是这样,那么在弹出窗口显示给用户之前,将执行预先操作(例如暂停视频),只有用户留在网页上时才会发生回调。
我的逻辑是在事件处理程序的主体中启动setTimeout。直到用户按下按钮后,setTimeout才会执行。在他们按下按钮后,它立即触发。在本例中,setTimeout不会调用回调函数,而是代理一个函数,该函数使用20ms的延迟执行另一个回调的超时。如果用户留在页面上,则执行回调。如果没有,那么将附加另一个处理程序到onunload上,该处理程序清除将调用回调的超时,确保永远不调用回调。我只有在Firefox、IE和Chrome中检查过它,但迄今为止在所有三个浏览器中都没有问题。
我希望这可以帮助像我一样受到广泛拒绝的人们。这段代码可能不完美,但我认为它走在正确的轨道上。