ポストバック上のページ内でdivのスクロール位置を維持する
-
11-09-2019 - |
質問
ASPXページ内にDIVがあり、オーバーフローが自動に設定されています。 DIVの内容は動的に作成され、リンクボタンのリストで構成されています。
<div id="div1" style="overflow: auto; height: 100%;">
.....
</div>
Divでスコールダウンしてリンクボタンのいずれかをクリックすると、ページのリロードがDiv内のスクロール位置を失い、Divの上部に連れて行きます。それを防ぐ方法はありますか?
これはページ内のDIV用であることに注意してください。 Page.MaintainScrollPositionOnPostBack()
動作しません。
解決
Jeff Sがこの状況を処理する1つの方法に言及したように、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を要素に直接入れることはありませんが、単なる例です。代わりにクッキーに巻物の位置を保存することもできます。
他のヒント
最も簡単な方法は、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);
}
}
使用法:
<general:ScrollSaverPanel runat="server">
<Content>
<stwrw:Group runat="server" ID="rootGroup"/>
</Content>
</general:ScrollSaverPanel>
一部の人々は、スクロール位置を保存することを唯一の目的にしてupdatepanelを使用したくないので... :)
それを行う1つの方法は、DIVの装着イベントで、ScrollLeftとScrolltopのプロパティからの値をキャプチャすることです。これらの値を非表示のテキストボックス(ES)に保存します。郵便番号では、テキストボックスの値を使用してプロパティをリセットします。
リンクボタンが押されるとどうなりますか?ポストバック中にどのような処理が発生しますか?
これらの質問への回答に応じて、ポストバックを完全に取り除き、必要な操作を純粋にクライアント側を実行することを調査することをお勧めします。
(私は現在、クライアントのためにこの種の変換を実行しています。)