代码改变世界

关于保持页面滚动条位置的一些体会

2005-09-01 13:45  胖子  阅读(3226)  评论(5编辑  收藏  举报
在一个很长的列表中进行操作,当用户触发PostBack事件的时候,需要保持滚动条所在位置。搜索了一下,发现有两种方法可以实现。第一种,在msdn中找到的,设置Page的SmartNavigation(智能导航)属性为True。原文的备注是这样说的:


在大多数情况下不要在代码中设置该属性。在 .aspx 文件的 @ Page 指令中将 SmartNavigation 属性设置为 true。请求该页时,动态生成的类将设置该属性。

Internet Explorer 5.5 或更高版本浏览器请求页时(或稍后),智能导航将通过执行下列功能提高用户对该页的操作能力:

  • 消除导航导致的闪烁。
  • 从一页移动到另一页时保持滚动位置。
  • 保持导航之间的元素焦点。
  • 在浏览器的历史记录中只保留最后一页的状态。

智能导航最适用于需要频繁回发但是其可是内容在返回时不会发生显著更改的 ASP.NET 页。在决定是否将该属性设置为 true 时,请仔细考虑这一点。



对aspx页面来说,真的是很简单,只需要在页面头的@ Page后面多加一个SmartNavigation="True"就ok了,经简单的测试,没有问题,显示效果良好。但实际应用中却发现了问题。报告有js脚本错误,无论如何也保持不了滚动条的状态。经分析,发现是该页面调用了ascx(Custom Control)的缘故,且拉长页面的也正是拜ascx控件所赐。于是乎,考虑将SmartNavigation="True"添加到ascx页面中。结果,失败!ascx不支持@Page指令!虽说ascx也是一个页面,但和aspx还是有区别的。看来这种方法是解决不了这个问题的,只得令寻他法。

经再次搜索,发现有人用js脚本写过这个方法(感谢宝玉提供的js)。js是在客户端运行的,只要我的aspx页面能解析到客户端,不都是html文件么,从理论上说,用js的方法是可以实现的。于是马上动手试验,结果,成功!虽然当页面内容很多的时候有一个稍微明显的闪动,但滚动条可以保持在PostBack前的位置,与需求相符,问题解决。


ps:另附js脚本



<script language="javascript">
<!--
//  获取当前文件名
function getFileName()
{
    
var url = this.location.href;
    
var pos = url.lastIndexOf("/");
    
if(pos == -1)
        pos 
= url.lastIndexOf("\\");
    
var filename = url.substr(pos+1);
    
return filename;
}


function fnLoad()
{
    
with(window.document.body)
    
{
        addBehavior (
"#default#userData");    // 使得body元素可以支持userdate
        load("scrollState" + getFileName());    // 获取以前保存在userdate中的状态
        scrollLeft 
= getAttribute("scrollLeft");    // 滚动条左位置
        scrollTop = getAttribute("scrollTop");

    }

}

function fnUnload()
{
    
with(window.document.body)
    
{
        setAttribute(
"scrollLeft",scrollLeft);
        setAttribute(
"scrollTop",scrollTop);
        save(
"scrollState" + getFileName());    
        
// 防止受其他文件的userdate数据影响,所以将文件名加上了
        // userdate里的数据是不能跨目录访问的
    }

}


window.onload 
= fnLoad;
window.onunload 
= fnUnload;
// -->
</script>