在这个问题上我真的很感激你的帮助。我已经搜索了SO和谷歌寻找解决这个问题的方法,并没有找到任何100%有效的方法。这是我的问题(请原谅我对如何设置页面的描述):
我有一个包含在母版页中的页面。这个页面使用AjaxControlToolkit TabContainer,它在一个UpdatePanel中。每个TabPanel加载一个不同的用户控件,每个用户控件可以包含1:M输入表单,这些表单根据用户是否想要在控件中添加/编辑数据而显示。所有这些功能都工作得很好,但有时这些表单会在视窗内脱离视图。
为了尽量减少用户必须做的滚动量,我使用PageRequestManager实现了一个jQuery动画事件处理程序。本质上,我正在做的是调用ShowForm服务器端方法,该方法反过来构建一些JavaScript并将其注入endRequest上的页面。以下是服务器端代码:
private void ShowForm(bool pShowForm) {
fsAdd.Visible = pShowForm;
if (pShowForm) {
LoadScript(FocusOnFormScript("control_client_id"), "control_client_id");
}
}
protected void DropDownList_OnSelectedIndexChanged(object sender, EventArgs e) {
//SelectedIndexChanged processing.
MaintainFocusOnControl(KeepFocusOnFormScript("control_client_id"), "control_client_id");
}
private void LoadScript(string pScript, string pControlId) {
ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "focusControl_" + pControlId, pScript, true);
}
private void MaintainFocusOnControl(string pScript, string pControlId) {
ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "maintainFocus_" + pControlId, pScript, true);
}
/// <summary>
/// Scrolls to the form when it is made visible
/// </summary>
/// <param name="pControlId">The ClientID of the control to focus on after the form is made visible</param>
/// <returns></returns>
private string FocusOnFormScript(string pControlId) {
string script = @"
function FocusOnForm() {
var offset = $('#" + pControlId + @"').offset();
$('html, body').animate({
scrollTop: offset.top+200,
scrollLeft: offset.left+200},
'slow',
'easeOutQuart'
);
/* This removes the event from the PageRequestManager immediately after the desired functionality is completed so that multiple events are not added */
prm.remove_endRequest(FocusOnFormCaller);
}
prm.add_endRequest(FocusOnFormCaller);
function FocusOnFormCaller(sender, args) {
if (args.get_error() == undefined) {
FocusOnForm();
}
}";
return script;
}
/// <summary>
/// Scrolls to the form when it is made visible
/// </summary>
/// <param name="pControlId">The ClientID of the control to focus on after the form is made visible</param>
/// <returns></returns>
private string KeepFocusOnFormScript(string pControlId) {
string script = @"
function KeepFocusOnForm() {
var offset = $('#" + pControlId + @"').offset();
window.scrollTo(offset.left+500, offset.top+500); //just jump to the position; scrolling not needed
/* This removes the event from the PageRequestManager immediately after the desired functionality is completed so that multiple events are not added */
prm.remove_endRequest(KeepFocusOnFormCaller);
}
prm.add_endRequest(KeepFocusOnFormCaller);
function KeepFocusOnFormCaller(sender, args) {
if (args.get_error() == undefined) {
KeepFocusOnForm();
}
}";
return script;
}
这段代码在99%的情况下运行良好。1%的问题发生在我需要级联下拉列表的一个特定表单上。当DropDownList1被选中时,DropDownList2被正确填充,但是页面的滚动位置丢失,DropDownList2的视图被移动到视图的底部(还有另一个列表和表单在我现在描述的表单下面)。
我尝试了很多方法,包括:
- 不同的maintainScrollPositionOnPostBack设置
- PageRequestManager。_scrollPosition = null
- 将scrollTop存储在beginRequest中,并将其设置在endRequest
- 在单独的endRequest 中使用window.scrollTo(xPos,yPos)使用<<li> strong> document.documentElement.scrollTop = yPos
- jQuery的.scrollTop (yPos)
我觉得奇怪的是,如果我设置一个手动链接调用窗口。scrollTo或document.documentElement。scrollTop,它起作用了。我也可以使用已经注册的jQuery animate事件处理程序,但是在UpdatePanel刷新后页面会滚动到顶部,然后再次向下滚动。如果我将动画代码替换为窗口。scrollTo或document.documentElement。scrollTop不行
我通常做的是将scrollPos存储在隐藏的文本框中,当页面通过回发更新时,在渲染之前从文本框中获取值,然后通过一些javascript滚动到屏幕的那一部分…