我们有一个典型的Web应用程序,它本质上是一个具有大量屏幕的数据输入应用程序,其中一些具有一定程度的复杂性.我们需要提供标准功能,以确保用户忘记在导航或关闭浏览器之前单击"保存"按钮,他们会收到警告并可以取消(但仅当存在未保存或脏数据时).
我知道我必须做的事情的基础 - 实际上我确信在这些年之前我已经完成了所有工作(与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}true
if the form is dirty,false
* 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.';"); });
但请记住,如果您有从此页面重定向的条件,或者您想要允许成功发布表单,则需要在重定向或提交事件之前执行此操作,如下所示:
$('BODY').removeAttr('onbeforeunload');
...或者你会让自己陷入一个不断向你询问提示的循环中.
在我的情况下,我有一个很大的应用程序,我在Javascript中进行location.href重定向,以及表单发布,然后一些AJAX提交,然后在页面中内联成功响应.在任何这些条件下,我都必须捕获该事件并使用removeAttr()调用.
想要在Volomike优秀的jQuery代码上稍微扩展一下.
因此,我们有一个非常非常酷和优雅的机制,通过在保存之前导航远离更新的数据来实现防止无意中数据丢失的目标 - 即.更新页面上的字段,然后在单击"保存"按钮之前单击浏览器中的按钮,链接甚至后退按钮.
您需要做的唯一事情是向所有控件(尤其是保存按钮)添加"noWarn"类标记,这些控件会回发到网站,保存或不删除任何更新的数据.
如果控件导致页面丢失数据,即.导航到下一页或清除数据 - 您无需执行任何操作,因为脚本将自动显示警告消息.
真棒!做得好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似乎有绑定更改事件的错误(截至2010年2月).jQuery 1.3没关系.其次,我不能让jquery绑定onbeforeunload/beforeunload(我怀疑IE7,我正在使用).我尝试过不同的选择器("身体"),(窗口).我试过'.bind','.attr'.恢复到纯粹的js工作(我也看到了关于这个问题的一些关于SO的类似帖子):
$(document).ready(function() { $(":input").one("change", function() { window.onbeforeunload = function() { return 'You will lose data changes.'; } }); $('.noWarn').click(function() { window.onbeforeunload = null; }); });
注意我还使用了':input'选择器而不是枚举所有输入类型.严格矫枉过正,但我觉得很酷:-)