页面很长的话,要在PostBack后保持PostBack前的页面位置,在ASP.NET 1.*里可以使用SmartNavigation。但SmartNavigation有不少问题,包括在IE外的浏览器里不工作等。对此,解决方案是,在页面PostBack前,通过客户端脚本和隐藏控件记住当前页面位置,在PostBack后,把页面位置赋值给隐藏控件,然后在页面装载后用客户端脚本来设置页面位置,譬如可以参考CodeProejct上的这篇文章
Crossbrowser SmartNavigation Alternative
ASP.NET 2.0里提供了这样的一个方案,可以通过设置
<%@ Page MaintainScrollPositionOnPostBack=”true” %>
或在编码里设置
Page.MaintainScrollPositionOnPostBack = true;
或在web.config里设置
<pages maintainScrollPositionOnPostBack=”true” />
来达成。
用Reflector查看,在Page类的ProcessRequestMain里有这样的一句
if (this.MaintainScrollPositionOnPostBack)
{
this.LoadScrollPosition();
}
在LoadScrollPosition()里,
internal void LoadScrollPosition()
{
if ((this._previousPagePath == null) && (this._requestValueCollection != null))
{
string text1 = this._requestValueCollection[“__SCROLLPOSITIONX”];
if ((text1 != null) && !int.TryParse(text1, out this._scrollPositionX))
{
this._scrollPositionX = 0;
}
string text2 = this._requestValueCollection[“__SCROLLPOSITIONY”];
if ((text2 != null) && !int.TryParse(text2, out this._scrollPositionY))
{
this._scrollPositionY = 0;
}
}
}
从提交值里的__SCROLLPOSITIONX和__SCROLLPOSITIONY获取值并且存到成员变量里,然后在BeginFormRender(由HtmlForm的RenderChildren调用)里输出到页面
if (this.MaintainScrollPositionOnPostBack && !this._requireScrollScript)
{
this.ClientScript.RegisterHiddenField(“__SCROLLPOSITIONX”, this._scrollPositionX.ToString(CultureInfo.InvariantCulture));
this.ClientScript.RegisterHiddenField(“__SCROLLPOSITIONY”, this._scrollPositionY.ToString(CultureInfo.InvariantCulture));
this.ClientScript.RegisterStartupScript(typeof(Page), “PageScrollPositionScript”, “\r\ntheForm.oldSubmit = theForm.submit;\r\ntheForm.submit = WebForm_SaveScrollPositionSubmit;\r\n\r\ntheForm.oldOnSubmit = theForm.onsubmit;\r\ntheForm.onsubmit = WebForm_SaveScrollPositionOnSubmit;\r\n” + (this.IsPostBack ? “\r\ntheForm.oldOnLoad = window.onload;\r\nwindow.onload = WebForm_RestoreScrollPosition;\r\n” : string.Empty), true);
this.RegisterWebFormsScript();
this._requireScrollScript = true;
}
看一下页面输出,有下面这样的语句
/WebSite5/WebResource.axd?d=oNWBOJESyPoXDbbBArijOg2&t=632619935818125000
……
……
<!–
–>
theForm.oldSubmit = theForm.submit;
theForm.submit = WebForm_SaveScrollPositionSubmit; //
theForm.oldOnSubmit = theForm.onsubmit;
theForm.onsubmit = WebForm_SaveScrollPositionOnSubmit; //
theForm.oldOnLoad = window.onload;
window.onload = WebForm_RestoreScrollPosition; //// –>
WebResource.axd提供了对应的脚本
function WebForm_GetScrollX() {
if (__nonMSDOMBrowser) {
return window.pageXOffset;
}
else {
if (document.documentElement && document.documentElement.scrollLeft) {
return document.documentElement.scrollLeft;
}
else if (document.body) {
return document.body.scrollLeft;
}
}
return 0;
}
function WebForm_GetScrollY() {
if (__nonMSDOMBrowser) {
return window.pageYOffset;
}
else {
if (document.documentElement && document.documentElement.scrollTop) {
return document.documentElement.scrollTop;
}
else if (document.body) {
return document.body.scrollTop;
}
}
return 0;
}
function WebForm_SaveScrollPositionSubmit() {
if (__nonMSDOMBrowser) {
theForm.elements[‘__SCROLLPOSITIONY’].value = window.pageYOffset;
theForm.elements[‘__SCROLLPOSITIONX’].value = window.pageXOffset;
}
else {
theForm.__SCROLLPOSITIONX.value = WebForm_GetScrollX();
theForm.__SCROLLPOSITIONY.value = WebForm_GetScrollY();
}
if ((typeof(this.oldSubmit) != “undefined”) && (this.oldSubmit != null)) {
return this.oldSubmit();
}
return true;
}
function WebForm_SaveScrollPositionOnSubmit() {
theForm.__SCROLLPOSITIONX.value = WebForm_GetScrollX();
theForm.__SCROLLPOSITIONY.value = WebForm_GetScrollY();
if ((typeof(this.oldOnSubmit) != “undefined”) && (this.oldOnSubmit != null)) {
return this.oldOnSubmit();
}
return true;
}
function WebForm_RestoreScrollPosition() {
if (__nonMSDOMBrowser) {
window.scrollTo(theForm.elements[‘__SCROLLPOSITIONX’].value, theForm.elements[‘__SCROLLPOSITIONY’].value);
}
else {
window.scrollTo(theForm.__SCROLLPOSITIONX.value, theForm.__SCROLLPOSITIONY.value);
}
if ((typeof(theForm.oldOnLoad) != “undefined”) && (theForm.oldOnLoad != null)) {
return theForm.oldOnLoad();
}
return true;
}
这个方案应该对常用的浏览器都有效