Maintain scroll position of a div within a page on postback

两盒软妹~` 提交于 2019-11-28 21:38:20

As Jeff S mentioned one way to handle this situation is using javascript to track the scroll position of the div and each time the page loads reset the scroll position to its previous value.

Here's some sample code:

<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>

In practice I wouldn't put the javascript directly in the elements but its just an example. You could also store the scroll position in a cookie instead.

The easiest way is to wrap the control in an UpdatePanel.

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);
    }
}

Usage:

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

Since some people don't want to use an Updatepanel for the sole purpose of saving scroll position... :)

One way to do it is to capture, in the onscroll event of the div, the values from the scrollLeft and scrollTop properties. Save those values in a hidden text box(es). On post back, use the values from the text boxes to reset the properties.

What happens when the link buttons are pressed? What processing occurs during the postback?

Depending on the answers to those questions, you may want to investigate getting rid of the postback altogether and performing the necessary operations purely client-side.

(I am currently performing this kind of conversion for a client.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!