【问题标题】:Maintain scroll position of a div within a page on postback在回发时保持页面内 div 的滚动位置
【发布时间】:2010-11-08 20:06:52
【问题描述】:

我在一个 aspx 页面中有一个 div,溢出设置为自动。 div 的内容是动态创建的,由链接按钮列表组成。

<div id="div1" style="overflow: auto; height: 100%;">
.....
</div>

当我在 div 中向下滑动并单击任何链接按钮时,页面重新加载会丢失 div 内的滚动位置并将我带到 div 的顶部。有什么办法可以防止这种情况发生吗?

请注意,这是针对页面内的 div 的。 Page.MaintainScrollPositionOnPostBack() 不起作用。

【问题讨论】:

    标签: asp.net html scroll postback scroll-position


    【解决方案1】:

    正如 Jeff S 提到的处理这种情况的一种方法是使用 javascript 来跟踪 div 的滚动位置,并且每次页面加载时都会将滚动位置重置为之前的值。

    这里有一些示例代码:

    <html>
    <body onload="javascript:document.getElementById('div1').scrollTop = document.getElementById('scroll').value;">
        <form id="form1" runat="server">
        <input type="hidden" id="scroll" runat="server" />
        <div id="div1" style="overflow: auto; height: 100px;" onscroll="javascript:document.getElementById('scroll').value = this.scrollTop">
            ...........<br />
            ...........<br />
            ...........<br />
            ...........<br />
            ...........<br />
            ...........<br />
            ...........<br />
            ...........<br />
            ...........<br />
            ...........<br />
            ...........<br />
            ...........<br />
            <asp:LinkButton ID="LinkButton1" runat="server" Text="test2"></asp:LinkButton>
        </div>
        <asp:LinkButton ID="LinkButton2" runat="server" Text="test1"></asp:LinkButton>
        </form>
    </body>
    </html>
    

    实际上,我不会将 javascript 直接放在元素中,而这只是一个示例。您也可以将滚动位置存储在 cookie 中。

    【讨论】:

      【解决方案2】:

      最简单的方法是将控件包装在 UpdatePanel 中。

      【讨论】:

        【解决方案3】:
        using System;
        using System.ComponentModel;
        using System.Web.UI;
        using System.Web.UI.WebControls;
        
        [ParseChildren(true, "Content")]
        public class ScrollSaverPanel: WebControl
        {
            [TemplateInstance(TemplateInstance.Single)]
            [PersistenceMode(PersistenceMode.InnerProperty)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            public ITemplate Content { get; set; }
        
            private HiddenField HiddenField { get; set; }
        
            protected override HtmlTextWriterTag TagKey
            {
                get
                {
                    return HtmlTextWriterTag.Div;
                }
            }
        
            protected override void OnInit(EventArgs e)
            {
                HiddenField = new HiddenField();
        
                var metaContainer = new WebControl(HtmlTextWriterTag.Div);
                metaContainer.Controls.Add(HiddenField);
                metaContainer.Style.Add(HtmlTextWriterStyle.Display, "none");
        
                Controls.Add(metaContainer);
        
                var contentContainer = new WebControl(HtmlTextWriterTag.Div);
                Controls.Add(contentContainer);
        
                Content.InstantiateIn(contentContainer);
        
                this.Style.Add(HtmlTextWriterStyle.Overflow, "auto");
                this.Attributes.Add("onscroll", string.Format("javascript:document.getElementById('{0}').value = this.scrollTop;", HiddenField.ClientID));
        
                base.OnInit(e);
            }
        
            protected override void OnPreRender(EventArgs e)
            {
                ScriptManager.RegisterStartupScript(this, this.GetType(), "setscroll", string.Format("javascript:document.getElementById('{0}').scrollTop = '{1}';", this.ClientID, HiddenField.Value), true);
                base.OnPreRender(e);
            }
        }
        

        用法:

        <general:ScrollSaverPanel runat="server">
            <Content>
                <stwrw:Group runat="server" ID="rootGroup"/>
            </Content>
        </general:ScrollSaverPanel>
        

        因为有些人不想使用更新面板来保存滚动位置... :)

        【讨论】:

          【解决方案4】:

          一种方法是在 div 的 onscroll 事件中捕获来自 scrollLeft 和 scrollTop 属性的值。将这些值保存在隐藏的文本框中。在回发时,使用文本框中的值重置属性。

          【讨论】:

            【解决方案5】:

            按下链接按钮时会发生什么?回发过程中会进行哪些处理?

            根据对这些问题的回答,您可能想要调查完全摆脱回发并纯粹在客户端执行必要的操作。

            (我目前正在为客户执行这种转换。)

            【讨论】:

            • 按下链接按钮时,它会填充页面上的图形控件。看起来在客户端执行它似乎是最好的方法
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-06-06
            • 2011-10-18
            • 1970-01-01
            • 2012-04-25
            • 2014-07-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多