20

我们有一个典型的 Web 应用程序,它本质上是一个数据输入应用程序,具有许多屏幕,其中一些具有一定程度的复杂性。我们需要提供标准功能,以确保用户在离开或关闭浏览器之前忘记单击“保存”按钮,他们会收到警告并可以取消(但仅在存在未保存或脏数据时)。

我知道我必须做的基础知识——事实上,我确信这些年来我已经完成了这一切(与 onbeforeunload 相关,跟踪页面的“脏”状态等...... ) 但在我再次开始编写此代码之前,是否有人对已经存在的库(免费或其他方式)有一些建议会有所帮助?

4

6 回答 6

19

一块拼图:

/**
 * Determines if a form is dirty by comparing the current value of each element
 * with its default value.
 *
 * @param {Form} form the form to be checked.
 * @return {Boolean} <code>true</code> if the form is dirty, <code>false</code>
 *                   otherwise.
 */
function formIsDirty(form)
{
    for (var i = 0; i < form.elements.length; i++)
    {
        var element = form.elements[i];
        var type = element.type;
        if (type == "checkbox" || type == "radio")
        {
            if (element.checked != element.defaultChecked)
            {
                return true;
            }
        }
        else if (type == "hidden" || type == "password" || type == "text" ||
                 type == "textarea")
        {
            if (element.value != element.defaultValue)
            {
                return true;
            }
        }
        else if (type == "select-one" || type == "select-multiple")
        {
            for (var j = 0; j < element.options.length; j++)
            {
                if (element.options[j].selected !=
                    element.options[j].defaultSelected)
                {
                    return true;
                }
            }
        }
    }
    return false;
}

还有一个

window.onbeforeunload = function(e)
{
    e = e || window.event;  
    if (formIsDirty(document.forms["someFormOfInterest"]))
    {
        // For IE and Firefox
        if (e)
        {
            e.returnValue = "You have unsaved changes.";
        }
        // For Safari
        return "You have unsaved changes.";
    }
};

总结一下,你会得到什么?

var confirmExitIfModified = (function()
{
    function formIsDirty(form)
    {
        // ...as above
    }

    return function(form, message)
    {
        window.onbeforeunload = function(e)
        {
            e = e || window.event;
            if (formIsDirty(document.forms[form]))
            {
                // For IE and Firefox
                if (e)
                {
                    e.returnValue = message;
                }
                // For Safari
                return message;
            }
        };
    };
})();

confirmExitIfModified("someForm", "You have unsaved changes.");

您可能还希望将beforeunload事件处理程序的注册更改为使用LIBRARY_OF_CHOICE的事件注册。

于 2008-09-26T16:20:39.093 回答
13

如果你使用 jQuery,这里有一个简单的技巧:

$('input:text,input:checkbox,input:radio,textarea,select').one('change',function() {
  $('BODY').attr('onbeforeunload',"return 'Leaving this page will cause any unsaved data to be lost.';");
});

但是请记住,如果您有从该页面重定向的条件,或者您希望允许成功的表单发布,您需要在重定向或提交事件之前执行此操作,如下所示:

$('BODY').removeAttr('onbeforeunload');

...否则你会让自己陷入一个不断询问你提示的循环中。

在我的例子中,我有一个很大的应用程序,我在 Javascript 中执行 location.href 重定向,以及表单发布,然后一些 AJAX 提交然后返回页面中的内联成功响应。在任何这些情况下,我都必须捕获该事件并使用 removeAttr() 调用。

于 2009-04-10T05:37:54.237 回答
8

想稍微扩展一下 Volomike 优秀的 jQuery 代码。

因此,有了这个,我们有一个非常酷和优雅的机制来实现通过在保存之前远离更新的数据来防止意外数据丢失的目标 - 即。更新页面上的字段,然后单击浏览器中的按钮、链接甚至返回按钮,然后单击“保存”按钮。

您唯一需要做的就是向所有控件(尤其是保存按钮)添加一个“noWarn”类标签,这些控件(尤其是保存按钮)会返回网站,保存或不删除任何更新的数据。

如果控件导致页面丢失数据,即。导航到下一页或清除数据 - 您无需执行任何操作,因为脚本会自动显示警告消息。

惊人的!干得好沃洛迈克!

只需将 jQuery 代码如下:

$(document).ready(function() {

    //----------------------------------------------------------------------
    // Don't allow us to navigate away from a page on which we're changed
    //  values on any control without a warning message.  Need to class our 
    //  save buttons, links, etc so they can do a save without the message - 
    //  ie. CssClass="noWarn"
    //----------------------------------------------------------------------
    $('input:text,input:checkbox,input:radio,textarea,select').one('change', function() {
        $('BODY').attr('onbeforeunload',
        "return 'Leaving this page will cause any unsaved data to be lost.';");
    });

    $('.noWarn').click(function() { $('BODY').removeAttr('onbeforeunload'); });

});
于 2009-06-19T16:26:18.247 回答
7

除了 Lance 的回答之外,我刚刚花了一个下午试图让这个片段运行。首先,jquery 1.4 似乎存在绑定更改事件的错误(截至 2010 年 2 月)。jQuery 1.3 还可以。其次,我无法让 jquery 绑定 onbeforeunload/beforeunload(我怀疑我正在使用的 IE7)。我尝试了不同的选择器,(“body”),(window)。我试过'.bind','.attr'。恢复到纯 js 工作(我还看到了一些关于这个问题的类似帖子):

$(document).ready(function() {
    $(":input").one("change", function() {
        window.onbeforeunload = function() { return 'You will lose data changes.'; }
    });
    $('.noWarn').click(function() { window.onbeforeunload = null; });
});

注意我还使用了 ':input' 选择器,而不是枚举所有输入类型。严格来说是矫枉过正,但我​​认为这很酷:-)

于 2010-02-08T07:18:19.123 回答
2

我创建了一个 jQuery插件,可用于为 Web 应用程序实现警告未保存更改功能。它支持回发。它还包括一个链接,指向有关如何规范onbeforeunloadInternet Explorer 事件的行为的信息。

于 2010-03-31T20:36:57.813 回答
1

我对这个页面上列出的 jQuery 实现做了一点小小的改进。如果您启用了客户端 ASP.NET 页面验证并在页面上使用,我的实现将处理。

onBeforeLeave它避免了当页面由于验证失败而实际上没有在点击时发布时清除功能的“错误” 。只需no-warn-validate在导致验证的按钮/链接上使用该类。它仍然具有可用于具有(例如“另存为草稿”按钮)的no-warn控件的类。CausesValidation=false这种模式可能可以用于除 ASP.NET 之外的其他验证框架,所以我在这里发布以供参考。

 function removeCheck() { window.onbeforeunload = null; }

$(document).ready(function() {
    //-----------------------------------------------------------------------------------------
    // Don't allow navigating away from page if changes to form are made. Save buttons, links,
    // etc, can be given "no-warn" or "no-warn-validate" css class to prevent warning on submit.
    // "no-warn-validate" inputs/links will only remove warning after successful validation
    //-----------------------------------------------------------------------------------------
    $(':input').one('change', function() {
        window.onbeforeunload = function() {
            return 'Leaving this page will cause edits to be lost.';
        }
    });

    $('.no-warn-validate').click(function() {
        if (Page_ClientValidate == null || Page_ClientValidate()) { removeCheck(); }
    });

    $('.no-warn').click(function() { removeCheck() });
});
于 2010-03-08T16:14:49.313 回答