2010-01-27 58 views
1

我工作的ASP.NET 3.5的網站項目,並使用jQuery,如果他們修改了頁面提醒用戶,並試圖離開頁面,不保存,所以做這樣的事情:jQuery的自動回問題

var warning = "Please save changes you made."; 
var isDirty = false; 

$(document).ready(function() 
{ 

     $('input:text,input:checkbox,input:radio').bind('change', function() 
     { 

      isDirty = true; 

      $('input[type=submit]').bind('click', function(e) 
      { 

       isDirty = false; 
      }); 

      window.onbeforeunload = function() 
      { 

       if (isDirty) 
       { 

        return warning; 
       } 
      } 
     }); 
    }); 

它工作正常,但是當我在頁面上進行更改,然後在頁面上的下拉列表中選擇另一個項目(導致回發)時,我收到了警告,我不應該這樣做。在jQuery中實現此功能是可行的,即在真正離開頁面時發出警告,但忽略回傳,以及在這種情況下需要對腳本進行哪些更改?

好吧,我修改劇本咯,創建了一個隱藏字段保存回發之間的骯髒狀態,所以它看起來是這樣的:

var warn_on_unload = "Leaving this page will cause any unsaved data to be lost."; 
var previouslyDirty = false; 
var isDirty = false; 

$(window).load(function() 
{ 

    previouslyDirty = $('#dirtyFlag').val() == '1'; 

}); 

$(window).unload(function() 
{ 

     $('#dirtyFlag').val(previouslyDirty ? '1' : '0'); 
}); 

$(document).ready(function() 
{ 

     $('input:checkbox,input:radio').one('change', function() 
     { 

      isDirty = true; 

      previouslyDirty = true; 

     }); 



     $('input:text, textarea').keydown(function() 

     { 

      isDirty = true; 

      previouslyDirty = true; 

     }); 

     $('form').submit(function(e) 
     { 

      isDirty = false; 

      previouslyDirty = false; 

     }); 

     $('select').bind('change', function(e) 
     { 

      isDirty = false; 

      previouslyDirty = true; 

     }); 

     window.onbeforeunload = function() 
     { 

      if (isDirty || previouslyDirty) 
      { 

       return warn_on_unload; 

      } 
     } 

    }); 

未提交回發後,仍然表現不正確,它應該讓他們無一個警告,但保存骯髒的狀態,所以如果我改變下拉,回發沒有問題,但如果我嘗試離開頁面後,應該得到一個警告。另外,需要注意提交回發,即保存按鈕,顯然允許它們並清除先前設置的所有髒標誌。

+0

我可能是啞巴,但實際上提到的下拉菜單是做什麼的? – 2010-02-06 19:00:46

+0

@亞當。該特定的下拉菜單會更改外鍵值。但是這是一個更廣泛的問題,因爲我有各種不提交的按鈕,下拉菜單,嚮導按鈕等引起回發,並且只有當用戶離開頁面時,我才能對其中的任何人發出警告。 – Victor 2010-02-06 19:54:53

+0

那麼,這並不是特別的「答案」,更像想法:導航到其他網站或關閉一個頁面必須有不同的「代碼」,然後改變一些東西的值,所以雖然都調用卸載,但一定有不同的東西。 ..檢查與螢火蟲也許? – 2010-02-06 23:12:13

回答

2

由於我們已經jQuery的,我們用它來檢測表單是否已經改變展現在接受這個問題的答案What is the easiest way to detect if at least one field has been changed on an HTML form?

另外,我們知道,Web表單頁面只有一個單一的形式。 Webforms在通過鏈接處理回發時調用form.onsubmit()和form.submit()。

要跟蹤AutoPostBack事件中的原始序列化值,請將序列化表單數據存儲在隱藏字段中。

<asp:HiddenField id="serializedForm" runat="server" /> 

$(document).ready(function(){ 

    var theform = $('form'); 
    var serialized = theform.serialize(); 
    var previous = null; 

    // track original serialized across postbacks 
    var hidden = $('#<%# serializedForm.ClientID %>'); 
    if ('' == hidden.val()) { 
     serialized = hidden.val(); 
    } else { 
     hidden.val(serialized); 
    } 

    window.onbeforeunload = function(e) { 
     if (serialized != theform.serialize()) { 
      return "Are you sure you want to leave the page without saving?"; 
     } 
    } 

    // postback -> __doPostBack -> form.onsubmit -> here 
    theform.submit(function(){ 
     // keep in case of validation fail 
     previous = serialized; 

     // prevent the onbeforeunload prompt 
     serialized = theform.serialize(); 
    }); 

    // there might be ASP.NET validators 
    if (typeof(ValidatorOnSubmit) == "function") { 
     var asp_ValidatorOnSubmit = ValidatorOnSubmit; 
     ValidatorOnSubmit = function() { 
      var result = asp_ValidatorOnSubmit.apply(arguments); 
      if (!result) { 
       serialized = previous; 
      } 
      return result; 
     } 
    } 

}); 
+0

感謝您的回覆。我不明白這是如何處理未提交的回發,即一旦我改變了某些東西,我將無法做任何事情,導致回發沒有警告。 – Victor 2010-02-08 13:57:49

+0

是的,總是一個表單,它將在母版頁上運行。但我不認爲可以使用這種方法。當我點擊「保存」提交按鈕後,進行一些更改,我應該能夠關閉一個頁面沒有警告,因爲我剛剛保存了我的更改。我上面的代碼處理這種情況。 – Victor 2010-02-08 14:28:13

+0

@Victor我簡化了我的腳本 – 2010-02-08 14:30:06

1

您是否嘗試過捕獲表單的提交事件? (未提交按鈕的點擊,但實際提交)

也許這將解決這個問題..

$('form').submit(function(){isDirty = false;}); 

除非正常的鏈接也提交表單...

+0

感謝您的回覆。不,我沒有嘗試過。問題是我們使用母版頁,這是一個內容頁面,所以沒有表格名稱 – Victor 2010-01-27 23:33:49

+0

是的..但有一個表格標籤是嗎? (一個)。上面的代碼附加到表單標籤。 – 2010-01-27 23:44:30

+0

實際上,不,頁面內容完全在內容標籤 – Victor 2010-01-27 23:45:58

0

怎麼樣東西喜歡這個?

$(window).unload(function(event) 
{ 
    if (event.target.nodeName != "SELECT" && event.target.nodeName != "INPUT") { 
    $('#dirtyFlag').val(previouslyDirty ? '1' : '0'); 
    } 
}); 
​ 

如果這不起作用,你能告訴我什麼是event.target.nodeName在各種情況下叫什麼名字?

+0

感謝您的答覆。 event.target.nodeName的值總是'#document',因爲我在主頁面上有它 – Victor 2010-02-05 15:43:34

+0

這很令人驚訝。我已經使用ASP.NET很長一段時間了,但我認爲MasterPage的最終結果也是HTML。因此,如果SELECT(AutoPostback)上有事件,瀏覽器將始終知道事件的正確來源。我可以建議的下一件事是所有的回發都是通過名爲'__doPostBack'的函數觸發的。你可以做些什麼。 – 2010-02-06 11:16:34