« ココログでソースコードを見やすくする | トップページ | 「ゆるくないスタンプラリー」を頑張るための公共交通機関情報まとめ »

2014年5月20日 (火)

ボタン押したときに目的の位置までスクロールさせたい

なんかの一覧で、ボタン押すとそれに対応したセクションが表示されるんだけど、いちいちぶつ切りではなくて1ページ内でスクロールすれば別ボタンに対応している章も見られるようにしたいという場合。




単純なHTMLなら <A NAME="hoge"> の <A HREF="#hoge"> でやるんですけど、あ、古い、そうですか、僕はHTML 3.2あたりで育っててCSS嫌いな人間なもので、なんですか、id属性使えば<A>タグ以外でも自由自在に飛べるってことですか。じゃあまぁ <div ID="hoge"> とかでも。

で、 ASP.NET の C# でもって .NET Framework 上のWebアプリを作っていて、 GridView とか DataList とか使ってるんだけどその中のどっかへスクロールしたい、という話。




JavaScriptでやります。

とは言ってもC#から、HTMLにJavaScriptを出力するメソッド Page.ClientScript.RegisterStartupScript() を使って、こんな感じ。





System.Text.StringBuilder script = new System.Text.StringBuilder();
script.Append("<script language=\"javascript\">");
script.Append("window.attachEvent('onload',ScrollDiv);");
script.Append("function ScrollDiv(){");
script.Append(" var elemMasterDiv=document.getElementById('");
script.Append(this.div1.ClientID);
script.Append("');");
script.Append(" var elemTarget=document.getElementById('");
script.Append(this.DataList1.Items[10].FindControl("label1").ClientID);
script.Append("');");
script.Append(" elemMasterDiv.scrollTop = elemTarget.getBoundingClientRect().top - elemMasterDiv.getBoundingClientRect().top;");
script.Append("};");
script.Append("</script>");
this.ClientScript.RegisterStartupScript(this.GetType(), "ScrollDiv", script.ToString());



.aspxの方は例えばこんな。





<div id="div1" runat="server" style="overflow:auto; height:100px">
    <asp:DataList ID="DataList1" runat="server">
        <ItemTemplate>
            <asp:Label id="label1" runat="server" Text='<%# Eval("COL1") %>'></asp:Label>
        </ItemTemplate>
    </asp:DataList>
</div>



.aspx.cs の方でとりあえず初期表示します。





protected void Page_Load(object sender, EventArgs e)
{
DataTable inDt = new DataTable();
inDt.Columns.Add("COL1");
for (int i = 0; i < 90; i++)
{
inDt.Rows.Add(inDt.NewRow());
inDt.Rows[inDt.Rows.Count - 1]["COL1"] = i.ToString();
}
this.DataList1.DataSource = inDt;
this.DataList1.DataBind();
}



んでなんかのボタンのイベントハンドラに上記一連の RegisterStartupScript() を書いておけば、それを押した時点でこの例だと DataList の10行目へ飛びます。

this.DataList1.Items[10] って指定してるから。




要点は elemMasterDiv.scrollTop = elemTarget.getBoundingClientRect().top - elemMasterDiv.getBoundingClientRect().top; でしょうね。

getBoundingClientRect().top だとページ全体に対しての自分の絶対位置が返ってくるっぽいのに対し、<div>では自分の中でのスクロール量がほしいので、目的コントロールの getBoundingClientRect().top から<div>の getBoundingClientRect().top を引いてます。

あとは getElementById() に渡すIDを ClientID プロパティで取ってきてるくらいかなー。目的に合わせるにはそこの取得方法工夫してくださいね。




これdivタグでスクロールさせる場合の話なんで、ウインドウ全体をスクロールさせたい場合は、まぁなんか調べてやってください。






ブラウザのことはよく考えてません。手元の環境でうまくいったのでそれ書いてるだけです。IE8。

会社内のものだから統一された環境と考えていいのだ。

あー子会社も含むから本当に大丈夫かどうかは、どうかな。






2015/05/25に書きました。

« ココログでソースコードを見やすくする | トップページ | 「ゆるくないスタンプラリー」を頑張るための公共交通機関情報まとめ »

パソコン・インターネット」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: ボタン押したときに目的の位置までスクロールさせたい:

« ココログでソースコードを見やすくする | トップページ | 「ゆるくないスタンプラリー」を頑張るための公共交通機関情報まとめ »

AmazonSearch


最近のトラックバック

無料ブログはココログ