我在updatepanel中有一个ASP.NET FormView。我通过为FormView中的每个项目设置AutoPostBack = true来自动保存表单。
这意味着用户可以快速连续点击几个元素,几乎同时触发几个异步回发。
我遇到的问题是,当异步回发尚未完成时,用户可以继续向下滚动表单。浏览器总是滚动回到第一次回发时的位置。
Page.MaintainScrollPositionOnPostback设置为False。
我在ajax和jquery中尝试了各种各样的事情:
但我似乎总是只能访问第一个回发时的滚动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>
答案 0 :(得分: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);
答案 1 :(得分:0)
只需将Timer控件放在内容模板中即可。
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="5000" OnTick="Timer1_Tick">
</asp:Timer>
<asp:ImageButton ID="ImageButton1" runat="server" Height="350" Width="700" />
</ContentTemplate>
</asp:UpdatePanel>