javascript - 创建一个类似于beforeUnload的JavaScript函数,该函数在单击链接以显示自定义确认对话框时触发

标签 javascript jquery html onbeforeunload

在使用JavaScript的应用程序中,如果用户在保存数据之前尝试离开页面,则会显示典型的警报消息。

这是使用beforeunload事件完成的。此事件仅允许您更改和设置自定义文本,仅此而已。我了解到某些浏览器甚至不允许使用您的自定义文本!

因此,无论如何,在我的应用程序中,现在我都有一个看起来很漂亮的“对话”窗口,当我需要用户确认某些内容时,我会在整个应用程序中使用该对话框。

因此,理想情况下,我希望我的自定义对话框在用户尝试离开未保存更改的页面时显示。我什至可以在对话框中显示我的AJAX保存按钮,以供用户从那里保存!

我们知道这根本是不可能的,似乎使用了beforeunload事件。

因此,我想出了另一个计划,而不是简单地放弃并说这不可能像每个StackOverflow问题和有关此事的博客文章所说的那样,我更愿意冒险过去,因为我知道可以做到!

我有一个方法的想法,然后我的想法来了,我发现了一个实际上已经在做的网站! Facebook

因此,在我的应用中,我有一个全局JavaScript变量var unsavedChanges = false;现在,只要在页面上对我说构成“更改”的“表单”字段和操作进行更改,然后在这些项目上发生这种情况时,我就将设置var unsavedChanges = true;
unsavedChanges是我确定是否显示beforeunload事件警报的方式。

因此,我想使用相同的变量,而不是简单地显示beforeunload事件警报,而是希望在另一个事件中使用它。

我想在所有链接上设置一个click事件。因此,只要在我的应用程序中单击链接,它就会检查unsavedChanges,如果是true,我将显示自己的自定义jQuery Dialog窗口。它的内部将有一个保存按钮来保存内容,并有一个取消按钮和一个继续到该目的地的按钮。它还应该将unsavedChanges设置为false,这有望防止window.beforeunload事件直接在之后触发。

现在,我提到Facebook似乎完全按照我在消息页面上概述的或至少非常相似的方式进行操作。

通过链接退出请点击

这是当单击 LINK ...时正在执行的操作的屏幕截图。

通过非链接退出单击

现在,当您绕过链接单击并尝试关闭窗口或在地址栏中输入新的URL时,基本上是其他任何类型的非链接单击的页面退出,然后回退到beforeunload事件的默认浏览器行为

因此,如果您看一下Facebook所做的事情,那么我上面所描述的似乎是可行的,看来我概述的方式是可以实现的。显然,您失去了“非链接点击退出自定义对话框”的支持,但是无论如何它都不存在,因此在这里没有任何损失,您将在所有链接点击中添加对它的支持,太棒了!

现在我有了这个主意,但是我不知道如何正确地将其编码为100%,我需要帮助。

例如一些我不知道如何处理的问题...

  • 如果单击了链接,并且该链接上已经具有click事件,那么我们如何使用此新的click事件以及现有的click事件?
  • 一些链接可能不保证这种行为。如果我有一个链接,该链接上已经具有click事件,并且该事件执行的操作类似于删除某项或将某项添加到页面,那么它甚至都没有试图将页面放在第一位,因此它不应显示对话框!因此,需要某种方式将链接设置为不具有此功能。同样也可能默认情况下,不能在其中没有链接的链接上设置它。 <a href=""><a href="#"><a href="#targetName">这些显然不应该具有单击事件!

  • 因此,这就是我现在看到Facebook采取某种行动的全部想法!我很想听听更多的想法,想法以及与此相关的任何内容。如果从这个问题中找到一个好的解决方案,那么这将是一个非常不错的博客文章,因为数百人似乎真的想要此功能,而且我知道我自己已经有很多年了。

    最佳答案

    因此,我们已经建立了获取非链接拦截的功能,您将需要使用onbeforeunload,因此我什至不会深入探讨。对于链接,您可以拦截click事件,然后评估location object以了解将您带到何处。在此基础上做出决定。对我来说,我认为主机,路径名和协议(protocol)是要检查的。您可以根据需要检查所有这些内容。如果有任何不同,他们将离开您。

    更改jQuery选择器,因为您将忽略某些链接。

    // Just going to assume this is true for arguments sake.
    var unsavedChanges = true;
    
    $('a').click(function () {
        // Properties to compare between link and current location
        // https://developer.mozilla.org/en-US/docs/Web/API/Location
        var toCheck = ['host', 'pathname', 'protocol'];
        var toCheckL = toCheck.length;
    
        return function (e) {
            // Skip this if there's no changes
            if (!unsavedChanges) return true;
    
            // Just to be sure
            if (this.constructor !== HTMLAnchorElement) {
                return true;
            }
    
            // Start off assuming they want to stay
            // because we can't stand being left again        
            var staying = true;
    
            for (var i = 0; i < toCheckL; i++) {
                var arg = toCheck[i];
    
                if ( this[arg] !== window.location[arg] ) {
                    // If anything doesn't match, just move on and let her go
                    staying = false;
                    break;
                }
            }
    
            if ( !staying ) {
                // Do whatever you want here
                // Return false to stop the link
                // Recommend you reference this.href if you
                // decide to let them leave after all
                alert("Blocked");
                return false;
            }
    
            alert("Baby come back...");
        };
    }());
    

    http://jsfiddle.net/dt502efv/

    关于javascript - 创建一个类似于beforeUnload的JavaScript函数,该函数在单击链接以显示自定义确认对话框时触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26500997/

    相关文章:

    javascript - jquery this 和 $(this)

    javascript - jQuery : input type text value is showing in alert

    jquery - 选择行时如何从所有相同级别的表行中删除 CSS 类?

    javascript - 强制元素在文本框外单击时隐藏

    Javascript : "extend" an object without an instance

    javascript - 防止父页面向下滚动到 iframe

    javascript - React (NextJS) 函数未定义

    javascript - HTML div 在写入文本时更改宽度

    javascript - javascript socket io可以监听unix sock吗?

    javascript - 如何防止在 iframe 中浏览时打开新选项卡或窗口