繁体   English   中英

当用户离开时触发事件

[英]Trigger an event when user navigates away

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

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

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

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

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

最简单的方法:

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只是作为额外的预防措施,而不是作为主要机制。 众所周知会引起问题。

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

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

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

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

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

在我的很多项目中,这里提到的方法是不稳定的 这对我的作品的唯一一件事就是绑定事件为主体元素的原始属性

<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()');
}

另外, important ,属性中没有参数,并且函数必须在全局窗口范围内,否则什么都不会发生。

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

这有点痛苦,因为至少在版本 92.0.4515.131 中,Chrome 似乎正在将安全螺钉固定在您可以在beforeunloadbeforeunload 例如,我无法发出同步 ajax 请求。

如果用户有机会回到您的网站,您可以等到那时再处理他们关闭了一个窗口(这在我的用例中确实有效),请知道在beforeunload期间设置 cookie 目前似乎是公平的游戏事件。 即使在我关闭浏览器时也能工作。 似乎涵盖了除重启计算机之外的大多数内容。

这是一个参考示例(从这个 SO question 中窃取了getCookie ):

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";
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM