客户端/ JS框架的“未保存的数据”保护?
我们有一个典型的Web应用程序,实质上是一个数据input应用程序,有很多的屏幕,其中一些有一定程度的复杂性。 我们需要提供这样的标准function,以确保用户在浏览或closures浏览器之前忘记点击“保存”button,他们会得到一个警告,并可以取消(但只有当有未保存或脏的数据)。
我知道我必须做的事情的基础知识 – 事实上,我相信这些年来,我已经完成了所有工作(配合onbeforeunload,跟踪页面的“脏”状态等等)。 ),但是在我开始编写这个版本之前,有没有人对已经在那里(免费或其他)的图书馆有一些帮助?
一个难题是:
/** * 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
的事件注册。
如果你使用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.';"); });
但是请记住,如果您有条件从此页面redirect,或者您想允许成功的表单发布,则需要在redirect或提交事件之前执行此操作,如下所示:
$('BODY').removeAttr('onbeforeunload');
…或者你会陷入一个循环,不停地询问你的提示。
在我的情况下,我有一个大的应用程序,我正在做Javascript的location.hrefredirect,以及forms张贴,然后一些AJAX提交,然后回来,在页面内嵌成功响应。 在任何这些情况下,我必须捕获该事件并使用removeAttr()调用。
想要在Volomike优秀的jQuery代码上稍微扩展。
所以有了这个,我们有一个非常非常酷和优雅的机制来实现在保存之前通过从更新的数据导航而防止无意的数据丢失的目的 – 即, 点击页面上的更新字段,然后点击浏览器中的button,链接,甚至后退button,然后点击保存button。
你唯一需要做的就是添加一个“noWarn”类标签到所有的控件(特别是保存button),做一个回发到网站,保存或不删除任何更新的数据。
如果控件导致页面丢失数据,即。 导航到下一页或清除数据 – 您不需要执行任何操作,因为脚本会自动显示警告消息。
真棒! 干得好Volomike!
简单地使用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'); }); });
除了兰斯的回答,我只是花了一个下午试图让这个片段运行。 首先,jquery 1.4似乎有错误的绑定变化事件(截至10年2月)。 jQuery 1.3是好的。 其次,我不能让jquery绑定onbeforeunload / beforeunload(我怀疑IE7,我正在使用)。 我试过不同的select器(“body”),(窗口)。 我试过'.bind','.attr'。 恢复到纯js工作(我也看到了一些关于这个问题的类似的post):
$(document).ready(function() { $(":input").one("change", function() { window.onbeforeunload = function() { return 'You will lose data changes.'; } }); $('.noWarn').click(function() { window.onbeforeunload = null; }); });
注意我也使用了':input'select器而不是枚举所有的inputtypes。 严格矫枉过正,但我认为这很酷:-)
我已经创build了一个jQuery 插件 ,可以用来实现Web应用程序的warn-on-unsaved-changesfunction。 它支持回发。 它还包含有关如何规范Internet Explorer的onbeforeunload
事件行为的信息的链接。
我对这个页面上列出的jQuery实现做了一点改进。 我的实现将处理,如果你有客户端ASP.NET页面validation启用和在页面上使用。
它避免了由于validation失败而导致页面实际上没有发布时,清除onBeforeLeave
函数的“错误”。 只需在导致validation的button/链接上使用no-warn-validate
类。 对于具有CausesValidation=false
(例如“另存为草稿”button)的控件,它仍然具有no-warn
类。 这种模式可能可以用于ASP.NET以外的其他validation框架,所以我在这里发布供参考。
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() }); });