客户端/ JS框架的“未保存的数据”保护?

问题描述:

我们有一个典型的Web应用程序,它基本上是一个数据输入应用程序,其中有许多屏幕,其中一些具有某种程度的复杂性。我们需要提供这种标准功能,以确保用户忘记点击“保存”按钮,然后导航或关闭浏览器,他们会收到警告并可以取消(但只有当存在未保存或脏数据时)。客户端/ JS框架的“未保存的数据”保护?

我知道我必须做的事情的基础知识 - 事实上,我确信在过去几年中我已经完成了所有工作(与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; 
} 

And another

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

感谢所有的样本......虽然我仍然在如何处理不陷阱回传和处理一些Ajax面板的问题,但我仍然在这里工作。 – 2008-10-09 03:24:32

如果你使用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'); 

...或者你会得到自己在一个循环中,保存着问你的提示。

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

+0

现在,我在这个主题上找到了更好的解决方案,只有三行。 – 2014-08-15 10:35:27

想要在Volomike优秀的jQuery代码上稍微扩展。因此,通过这种方式,我们有一个非常非常酷和优雅的机制,通过在保存之前从更新的数据导航来实现防止无意中数据丢失的目标 - 即,更新的页面上的字段,然后单击浏览器中的按钮,链接或甚至后退按钮,然后单击保存按钮。

您需要做的唯一事情就是向所有控件(特别是保存按钮)添加一个“noWarn”类标签,该标签将回发到网站,保存或不删除任何更新的数据。

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

太棒了!干得好Volvolike!

只需拥有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,我正在使用)。我尝试了不同的选择器,(“body”),(窗口)。我试过'.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; }); 
}); 

注意我也用了“:输入”选择,而不是枚举所有的输入类型。严重矫枉过正,但我​​认为它很酷:-)

+0

+1不适用于IE,除非您使用vanilla js进行绑定。 – 2010-03-08 17:33:30

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

它避免了由于验证失败而导致页面实际上没有发布时,清除onBeforeLeave函数的“错误”。只需在导致验证的按钮/链接上使用no-warn-validate类。在(例如“另存为草稿”按钮)的控件上,它仍然具有no-warn类。这种模式可能可以用于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() }); 
}); 

我已经创建了一个jQuery plug-in可用于实现暖机上未保存的更改Web应用程序的功能。它支持回发。它还包含有关如何标准化Internet Explorer事件的行为的信息链接。