32

当用户关闭他的窗口/选项卡或通过单击链接导航离开时,我需要在 PHP 页面上调用其中包含几行代码的 JavaScript/jQuery 函数。我已经尝试过该onbeforeunload功能,但只有return "blah blah blah;"部分执行,其他所有内容都被忽略。我也尝试过.unloadjQuery 的方法,但由于某种原因,这段代码没有运行。

$(window).unload(function() {
    alert('blah blah blah');
});

请提出替代方案。谢谢..

4

4 回答 4

24

这是一个简单的工作示例。return回调中的任何内容unload都将显示在浏览器弹出确认中。

卸载前发送 Ajax 请求的工作示例 http://jsfiddle.net/alexflav23/hujQs/7/

最简单的方法是:

window.onbeforeunload = function(event) {
    // do stuff here
    return "you have unsaved changes. Are you sure you want to navigate away?";
};

在 jQuery 中:

$(window).on("beforeunload", function() {
    $.ajax("someURL", {
        async: false,
        data: "test",
        success: function(event) {
             console.log("Ajax request executed");
        }
    });
    return "This is a jQuery version";
});

查看浏览器的“网络”选项卡。您将看到请求是如何按照您的意愿发送的。只需发送适当的数据。

请记住,所有触发的操作都必须是同步的,因此您只能发出同步的 ajax 请求。但是,以上内容对于任何目的都不是完全可靠的。

选择定期将用户数据备份到localStorage服务器并自动与服务器同步。保留window.onbeforeunload只是作为一种额外的预防措施,而不是作为主要机制。众所周知,它会导致问题。

于 2013-04-10T12:05:20.500 回答
2

这是一个老问题,但我想分享一种替代方法,该方法具有高一致性的好处:

与服务器建立 WebSocket 连接,当客户端离开时,WebSocket 连接将关闭。在服务器端,您可以在回调中检测关闭的连接并在服务器上运行您需要的任何代码。

在页面卸载时执行 Javascript 通常是不可靠的(如另一个答案中所述),因为它本质上与用户的意图不一致。这种方法总是有效的,尽管实施起来确实有点麻烦。

这确实将“离开前运行”代码的上下文从客户端更改为服务器端,但我想在大多数情况下,差异是无关紧要的。在客户端离开您的页面之前您想在客户端运行的任何内容都可能不会改变客户端看到的任何内容,因此在服务器端运行它可能没问题。如果您需要来自客户端的特定数据,您可以通过 WebSocket 将其发送到服务器。

我能想到的唯一可能导致意外行为的情况是,如果用户在没有实际导航的情况下丢失了 WS 连接,例如他们失去了互联网或让他们的计算机进入睡眠状态。这是否重要可能在很大程度上取决于您尝试执行的代码类型。

于 2020-02-07T22:19:12.703 回答
0

在我的许多项目中,这里提到的方法是不稳定的。唯一对我有用的是将事件绑定为body元素上的原始属性

<body onunload="my_function_unload()">

jQuery方法:

$('body').attr('onunload', 'my_function_unload()');

从 iframe:

<body onunload="window.parent.my_function_unload()">

jQuery方法:

$('<iframe />').load(function(){
    $body = $(this).contents().find('body');
    $body.attr('onunload', 'window.parent.my_function_unload()');
}

此外,重要的是,属性中没有参数,并且函数必须在全局窗口范围内,否则不会发生任何事情。

例如,常见错误如果您my_function_unload()被包裹在;( function( $ ) {...OR $(document).ready(function(){...AS中,则my_function_unload()必须在该私有范围之外。然后不要忘记使用jQuery而不是$前缀。(例如使用 Wordpress)

于 2020-03-22T14:19:38.813 回答
0

这是一种痛苦,因为至少在 92.0.4515.131 版中,Chrome 似乎正在将安全螺丝固定在您可以在beforeunload. 例如,我无法发出同步 ajax 请求。

beforeunload如果用户有任何机会返回您的站点,您可以等到那时处理他们关闭窗口(这在我的用例中确实有效),请知道在活动期间设置 cookie 目前似乎是公平的游戏. 甚至在我关闭浏览器时也可以使用。它似乎涵盖了除重启计算机之外的大多数内容。

这是一个参考示例(从这个 SO questiongetCookie中被盗):

function setCookie(name, value) {
    document.cookie =
        '{0}={1};expires=Fri, 31 Dec 9999 23:59:59 GMT;path=/;SameSite=Lax'
            .replace("{0}", name)
            .replace("{1}", value);
}

// https://stackoverflow.com/a/25490531/1028230
function getCookie(cookieName) {
    var b = document.cookie.match('(^|;)\\s*' + cookieName + '\\s*=\\s*([^;]+)');
    return b ? b.pop() : '';
}

window.addEventListener('beforeunload', function (e) {
    console.log('cookie value before reset: ' + getCookie('whenItHappened'));

    var now = +new Date();
    console.log("value to be set: " + now);
    setCookie('whenItHappened', now);

    return "some string if you want the 'are you sure you want to leave' dialog to appear";
});
于 2021-08-16T21:16:16.523 回答