我在aspx页面中有一个div,溢出设置为auto。 div的内容是动态创建的,由一系列链接按钮组成。
<div id="div1" style="overflow: auto; height: 100%;">
.....
</div>
当我在div中按下并单击任何链接按钮时,页面重新加载会丢失div中的滚动位置并将我带到div的顶部。有什么方法可以阻止这种情况吗?
请注意,这是针对页面内的div。 Page.MaintainScrollPositionOnPostBack()
不起作用。
答案 0 :(得分:14)
正如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中。
答案 1 :(得分:5)
最简单的方法是将控件包装在UpdatePanel中。
答案 2 :(得分: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>
由于有些人不想将Updatepanel用于保存滚动位置的唯一目的......:)
答案 3 :(得分:1)
一种方法是在div的onscroll事件中捕获scrollLeft和scrollTop属性中的值。将这些值保存在隐藏文本框中。在回发后,使用文本框中的值重置属性。
答案 4 :(得分:0)
按下链接按钮会发生什么?回发期间会发生什么处理?
根据这些问题的答案,您可能需要调查完全摆脱回发并完全在客户端执行必要的操作。
(我目前正在为客户进行此类转换。)