过去几天我一直在网上研究这个问题,答案总是“不”,你不能肯定地说,用户是留下还是离开(除了如果用户离开,你的应用程序就会退出工作的事实)。我讨厌“不”的答案。我想出了以下实用程序。
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 中检查它,但到目前为止它在所有三个中都有效,没有出现任何问题。
我希望这可以帮助像我一样对这个问题普遍给出的专利“否”感到沮丧的人们。这段代码可能并不完美,但我认为它在正确的轨道上。