Asp.net
如何避免在 AutoPostBack 上滾動 UpdatePanel?
我在更新面板中有一個 ASP.NET FormView。我通過為 FormView 中的每個項目設置 AutoPostBack=true 來自動保存表單。
這意味著使用者可以快速連續點擊一些元素並幾乎同時觸發一些非同步回發。
我遇到的問題是,當非同步回發尚未完成時,使用者能夠繼續向下滾動表單。瀏覽器總是滾動回它在第一次回發時所處的位置。
Page.MaintainScrollPositionOnPostback 設置為 False。
我在 ajax 和 jquery 中嘗試了各種各樣的東西:
- 頁面載入
- add_initializeRequest
- add_endRequest
- 文件就緒
- ETC..
但我似乎總是只能訪問第一次回發時的滾動 Y。
有沒有辦法在回發完成時檢索目前的滾動 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>
您可以綁定一個記錄目前滾動位置的函式,然後在每個 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);