2011-03-01 76 views
10

我在一個updatepanel內有一個ASP.NET FormView。我通過爲FormView中的每個項目設置AutoPostBack = true來自動保存表單。如何避免UpdatePane在AutoPostBack上滾動?

這意味着用戶可以快速連續點擊幾個元素,並幾乎同時發送一些異步回傳。

我遇到的問題是用戶能夠在異步回發尚未完成時繼續向下滾動表單。瀏覽器始終滾動回到第一次回發時的位置。

Page.MaintainScrollPositionOnPostback設置爲False。

我已經試過各種事情在AJAX和jQuery有:

  • 頁面加載
  • add_initializeRequest
  • add_endRequest
  • 的document.ready
  • 等。

但我總是似乎只能訪問滾動Y a這是第一次回傳。

當回發完成時,有什麼方法可以檢索當前的滾動Y,所以我可以停止滾動發生?或者也許可以禁用滾動行爲?

謝謝!


更新

感謝@chprpipr,我能得到這個工作。這裏是我的縮寫解決方案:

var FormScrollerProto = function() { 
    var Me = this; 
    this.lastScrollPos = 0; 
    var myLogger; 

    this.Setup = function (logger) { 
     myLogger = logger; 
     // Bind a function to the window 
     $(window).bind("scroll", function() { 
      // Record the scroll position 
      Me.lastScrollPos = Me.GetScrollTop(); 
      myLogger.Log("last: " + Me.lastScrollPos); 
     }); 
    } 

    this.ScrollForm = function() { 
     // Apply the last scroll position 
     $(window).scrollTop(Me.lastScrollPos); 
    } 

    // Call this in pageRequestManager.EndRequest 
    this.EndRequestHandler = function (args) { 
     myLogger.Log(args.get_error()); 
     if (args.get_error() == undefined) { 
      Me.ScrollForm(); 
     } 
    } 

    this.GetScrollTop = function() { 
     return Me.FilterResults(
       window.pageYOffset ? window.pageYOffset : 0, 
       document.documentElement ? document.documentElement.scrollTop : 0, 
       document.body ? document.body.scrollTop : 0 
      ); 
    } 

    this.FilterResults = function (n_win, n_docel, n_body) { 
     var n_result = n_win ? n_win : 0; 
     if (n_docel && (!n_result || (n_result > n_docel))) 
      n_result = n_docel; 
     return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result; 
    } 
} 

主頁:

...snip... 

var logger; 
    var FormScroller; 

    // Hook up Application event handlers. 
    var app = Sys.Application; 

    // app.add_load(ApplicationLoad); - use pageLoad instead 
    app.add_init(ApplicationInit); 
    // app.add_disposing(ApplicationDisposing); 
    // app.add_unload(ApplicationUnload); 

    // Application event handlers for component developers. 
    function ApplicationInit(sender) { 
     var prm = Sys.WebForms.PageRequestManager.getInstance(); 
     if (!prm.get_isInAsyncPostBack()) { 
      prm.add_initializeRequest(InitializeRequest); 
      prm.add_beginRequest(BeginRequest); 
      prm.add_pageLoading(PageLoading); 
      prm.add_pageLoaded(PageLoaded); 
      prm.add_endRequest(EndRequest); 
     } 

     // Set up components 
     logger = new LoggerProto(); 
     logger.Init(true); 
     logger.Log("APP:: Application init."); 

     FormScroller = new FormScrollerProto(); 
    } 

    function InitializeRequest(sender, args) { 
     logger.Log("PRM:: Initializing async request."); 
     FormScroller.Setup(logger); 
    } 

...snip... 

function EndRequest(sender, args) { 
     logger.Log("PRM:: End of async request."); 

     maintainScroll(sender, args); 

     // Display any errors 
     processErrors(args); 
    } 

...snip... 

function maintainScroll(sender, args) { 
     logger.Log("maintain: " + winScrollTop); 
     FormScroller.EndRequestHandler(args); 
    } 

我也試過致電EndRequestHandler(不得不刪除args.error檢查),看看它是否在滾動時減少閃爍,但它沒有。值得注意的是,完美的解決方案是停止瀏覽器試圖滾動 - 現在有一個瞬間的抖動,這在具有大量用戶羣的應用程序中是不可接受的。

(滾動頂部的代碼是不是我的 - 發現它在網絡上。)

(這裏是爲客戶方的生命週期有幫助的MSDN頁:http://msdn.microsoft.com/en-us/library/bb386417.aspx


更新3月7日:

我剛剛發現了一個極其簡單的方式做到這一點:

<script type="text/javascript"> 

var prm = Sys.WebForms.PageRequestManager.getInstance(); 

prm.add_beginRequest(beginRequest); 

function beginRequest() 
{ 
    prm._scrollPosition = null; 
} 

</script> 
+0

我知道這是一箇舊帖子,但謝謝你! – peter 2013-01-24 00:36:39

+0

'3月7日更新:'上面爲我工作 – Mark 2013-05-17 15:29:04

+0

這對我起初工作,然後它停下來...我不知道發生了什麼。它運行得很早,我不斷得到'Sys'是未定義的。在頁面生命週期中應該去哪裏? – 2013-12-04 16:27:01

回答

3

您可以綁定一個記錄當前滾動位置的函數,然後在每次endRequest之後重新應用它。它可能是這樣的:

// Wrap everything up for tidiness' sake 
var FormHandlerProto = function() { 
    var Me = this; 

    this.lastScrollPos = 0; 

    this.SetupForm = function() { 
     // Bind a function to the form's scroll container 
     $("#ContainerId").bind("scroll", function() { 
      // Record the scroll position 
      Me.lastScrollPos = $(this).scrollTop(); 
     }); 
    } 

    this.ScrollForm = function() { 
     // Apply the last scroll position 
     $("#ContainerId").scrollTop(Me.lastScrollPos); 
    } 

    this.EndRequestHandler = function(sender, args) { 
     if (args.get_error() != undefined) 
      Me.ScrollForm(); 
     } 
    } 
} 

var FormHandler = new FormHandlerProto(); 
FormHandler.Setup(); // This assumes your scroll container doesn't get updated on postback. If it does, you'll want to call it in the EndRequestHandler. 

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(FormHandler.EndRequestHandler); 
+0

謝謝你的代碼!你真的把我放在正確的軌道上。我不得不做幾個mod來讓它工作,但我做到了。我將編輯我的問題以包含最終解決方案。再次感謝! – 2011-03-03 04:24:00