Maintain scroll position of a div within a page on postback

33,680

Solution 1

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.

Solution 2

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

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

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... :)

Solution 4

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.

Share:
33,680
Nikhil
Author by

Nikhil

Seeking knowledge in the software world.

Updated on April 10, 2020

Comments

  • Nikhil
    Nikhil about 4 years

    I have a div within an aspx page with overflow set to auto. The contents of the div are dynamically created and consists of a list of link buttons.

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

    When I scoll down in the div and click on any of the link buttons, the page reload loses the scroll position inside the div and takes me to the top of the div. Is there any way to prevent that?

    Note that this is for a div inside the page. Page.MaintainScrollPositionOnPostBack() does not work.

  • Nikhil
    Nikhil almost 15 years
    When the link button is pressed, it populates a graph control present on the page. Looks like performing it on the client side seems like the best approach