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

时间:2014-10-22 05:44:55

标签: javascript jquery html onbeforeunload

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

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

所以无论如何,在我的应用程序中,我现在有一个看上去很好看的Dialog窗口,当我需要用户确认某些内容时,我会在整个应用程序中使用它。

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

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

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

我知道如何做到这一点然后在我的想法出现之后,我找到了一个实际已经做到的网站!的

所以在我的应用程序中我有一个全局JavaScript变量var unsavedChanges = false;现在,只要在页面上对表单字段和操作进行了更改,我说这构成了一个"更改",然后我会当这些项目发生时设置var unsavedChanges = true;

unsavedChanges是我决定是否显示我的beforeunload事件提醒。

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

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

现在我提到Facebook似乎完全按照我刚刚概述的那样做,或者至少在消息页面上非常相似。

按链接退出

以下是点击 LINK 时的动态屏幕截图....

enter image description here

通过非链接退出单击

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

http://i.imgur.com/KfpdbFS.png

因此,如果你看看Facebook正在做什么,我上面所描述的似乎是可能的,看起来我概述的是一种可实现的方式。显然你失去了Non-Link点击退出自定义Dialog支持,但它从来就不存在所以没有丢失,你在所有链接点击上添加了对它的支持,这太棒了!

现在我有了这个想法,但我不知道如何编写100%的代码,我需要帮助。

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

  • 如果点击了一个链接并且该链接上已经有点击事件,那么我们如何使用这个新的点击事件并使用现有点击事件?
  • 某些链接可能无法保证此行为。如果我有一个已经有点击事件的链接,并且该事件执行类似删除项目或将项目添加到页面的内容,那么它甚至不会尝试将页面放在首位,因此它不应显示对话框!因此,需要某种方式来设置链接以不具备此功能。也许它默认情况下不能设置在没有链接的链接上。 beforeunload<a href=""><a href="#">这些显然不会有点击事件!

所以这一点都是一个想法,我现在看到Facebook已经在某种程度上行动了!我很想听到更多的想法,想法,与此事有关的任何事情。如果一个好的解决方案来自这个问题,这将成为一个非常好的博客文章,因为数百人似乎真的想要这个功能,而且我知道我已经有多年了。

1 个答案:

答案 0 :(得分:1)

所以我们已经建立了非链接拦截你需要使用onbeforeunload,所以我甚至不会深入研究它。对于链接,您可以拦截点击事件,然后评估location object以查看它带您的位置。根据这个做出决定。对我来说,我认为主机,路径名和协议是要检查的。如果需要,您可以检查所有这些。如果其中任何一个不同,他们就会离开你。

更改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/