2008-09-26 77 views
18

我們有一個典型的Web應用程序,它基本上是一個數據輸入應用程序,其中有許多屏幕,其中一些具有某種程度的複雜性。我們需要提供這種標準功能,以確保用戶忘記點擊「保存」按鈕,然後導航或關閉瀏覽器,他們會收到警告並可以取消(但只有當存在未保存或髒數據時)。客戶端/ JS框架的「未保存的數據」保護?

我知道我必須做的事情的基礎知識 - 事實上,我確信在過去幾年中我已經完成了所有工作(與onbeforeunload搭配,追蹤頁面的「髒」狀態,等等......),但在我開始編碼這個再也沒有之前,有沒有人有一些建議,已經在那裏的圖書館(免費或其他),這將有助於?

回答

18

其中一塊拼圖:

/** 
* 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

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'); 

...或者你會得到自己在一個循環中,保存着問你的提示。

在我的情況下,我有一個很大的應用程序,我正在做location.href重定向的Javascript,以及表單發佈,然後一些AJAX提交,然後返回一個成功響應內聯在頁面中。在任何這些情況下,我必須捕獲該事件並使用removeAttr()調用。

+0

現在,我在這個主題上找到了更好的解決方案,只有三行。 – 2014-08-15 10:35:27

7

想要在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'); }); 

}); 
7

附加蘭斯的回答,我只花了一個下午的時間試圖讓這個段運行。 首先,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

1

我對此頁面上列出的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() }); 
}); 
2

我已經創建了一個jQuery plug-in可用於實現暖機上未保存的更改Web應用程序的功能。它支持回發。它還包含有關如何標準化Internet Explorer事件的行爲的信息鏈接。