我们有一个典型的Web应用程序,它本质上是一个具有大量屏幕的数据输入应用程序,其中一些屏幕具有一定程度的复杂性。我们需要提供标准功能,以确保用户忘记在导航或关闭浏览器之前单击“保存”按钮,他们会收到警告并可以取消(但仅当存在未保存或脏数据时)。
我知道我必须做的事情的基础知识 - 实际上我确信在这些年之前我已经完成了所有工作(与onbeforeunload相关,跟踪页面的“脏”状态等等) ...)但是在我开始对此进行编码之前,是否有人对已经存在的(免费或其他)图书馆提出了一些建议?
答案 0 :(得分: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
的事件注册。
答案 1 :(得分: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()调用。
答案 2 :(得分:7)
希望稍微扩展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'); });
});
答案 3 :(得分:7)
除了兰斯的回答,我只花了一个下午试图让这个片段运行。 首先,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'选择器而不是枚举所有输入类型。严格矫枉过正,但我觉得很酷: - )
答案 4 :(得分:2)
我创建了一个jQuery plug-in,可用于为Web应用程序实现未保存的警告更改功能。它支持回发。它还包含指向如何规范Internet Explorer onbeforeunload
事件行为的信息的链接。
答案 5 :(得分: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() });
});