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

Posted

技术标签:

【中文标题】用于“未保存数据”保护的客户端/JS 框架?【英文标题】:Client/JS Framework for "Unsaved Data" Protection? 【发布时间】:2010-09-13 12:25:54 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

拼图的一部分:

/**
 * 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 的事件注册。

【讨论】:

感谢您提供的所有示例......这里肯定有足够的东西供我使用,尽管我仍在努力解决如何处理不捕获回发和处理一些 ajax 面板。【参考方案2】:

如果你使用 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() 调用。

【讨论】:

目前,我在这个主题上找到了更好的解决方案,只需三行。【参考方案3】:

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

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

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

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

太棒了!干得好 Volomik!

只要有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'); );

);

【讨论】:

【参考方案4】:

除了 Lance 的回答之外,我刚刚花了一个下午试图让这个 sn-p 运行。 首先,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' 选择器,而不是枚举所有输入类型。严格来说是矫枉过正,但我​​认为这很酷:-)

【讨论】:

+1 表示无法在 IE 中工作,除非您使用 vanilla js 进行绑定。【参考方案5】:

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

【讨论】:

【参考方案6】:

我对本页上列出的 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() );
);

【讨论】:

以上是关于用于“未保存数据”保护的客户端/JS 框架?的主要内容,如果未能解决你的问题,请参考以下文章

获取未保存数据时的奇怪核心数据行为

Docker 提交 - 未保存数据库更改

如果要销毁未保存数据的视图,则显示警告

Atomikos:使用 PostgreSQL 时未保存数据

在 html/css/js 之上是不是有任何用于富 Web 客户端的框架?

初识 Angular 体会