miau's blog?

ASP.NET その3

さらに続き。
今回はまあ色々情報とか?


■SmartNavigation

ASP.NET では SmartNavigation というのが使えるわけですが。

Page.SmartNavigation プロパティ

・移動によって発生する点滅を除去します。
・ページ間を移動してもスクロール位置を保持します。
・移動の間で要素フォーカスを維持します。
・ブラウザの履歴に最後のページ状態だけを保持します。

結構良さそうなこと書いてありますが、これが結構大変だったりします。

smartnavigation="true"の際のJavaScriptの動作について - Insider.NET
PageクラスのsmartNavigationプロパティについて

この辺に色々問題が載ってますが・・・確かに「SmartNavigation を false にするとちゃんと動くのに」みたいな問題は結構体験しました。
でも一番の問題は、情報が少なすぎること。特にスクロールやフォーカス保持を行うためにどんな処理を行っているかという部分に関して、一切説明が無かったり。
この実現方法を知らないと、デバッグすらままならないんだけどな・・・。

実は SmartNavigation って結構大掛かりなことをやってるんですが・・・ポイント絞って説明してみます。

(1) SmartNavigation を true にすると、通常の処理に加えて以下の処理が行われる。
 ・ASP.NET で表示したページに __hifSmartNav という名前の iframe が作られる
 ・/aspnet_client/system_web/1_1_4322/SmartNav.js みたいな JavaScript が読み込まれる

(2) SmartNav.js の処理で、ASP.NET フォームの target 属性を __hifSmartNav に設定する。(正確には __hifSmartNav<timestamp> みたいな名前にリネームしてそれを使う)
 要するに、submit ボタンの押下時にその結果は iframe 内に表示される。

(3) さらに onLoad の処理で、iframe に読み込まれた HTML をごっそりメインの document にコピーするよう設定する

つまり、ページ全体を再読み込みしてるように見えるけど、実際は JavaScript で HTML を再生成しているだけ、と。
なるほどそれならスクロール位置とか保持されるわけです。

で、この原理が分かれば納得できることですが、PostBack 後に「ソースの表示」をしても、初回表示(PostBack 前)の状態しか表示できません。動的に生成された HTML を閲覧する方法を知らないと、ここでまた一苦労なんですが・・・たまたま知ってたので助かりました。

Internet Explorer Developer Toolbar Beta
GUI っぽい形式でみたい場合はこちら。

Full Source
HTML 形式でみたい場合はこちら。

こういう Web アプリケーション開発ツールも、一通りネタにしようと思いつつ忘れてた。
今度やろう。

あと iframe と JavaScript 使うアイディアは面白いと思った。
これと似たような原理でページの先読みスクリプトとかも作れそうですね。


と、ここまで書いておいてなんですが、本家の msdn。

Page.SmartNavigation Property (System.Web.UI)

「NOTE: This property is now obsolete.」なんて記述が。
早く言ってよ・・・。(数日前見たときは書いてなかった)

上記の動作、本当はシーケンス図とかにしてみようと思ってたんだけど、obsolete なら誰も使わないだろから、いいや。
状況によっては使ってもいいとは思うんだけど・・・今回は明らかに使いどころが間違ってたと思う。


■ViewState

なんか思い通りの動作をしてなくて、ViewState の内部を見たいことがありました。
結局問題は ViewState ではなく、上記の SmartNavigation の方だったんですが・・・折角なのでメモ。

ViewStateの【位置情報】について

このへんからのリンクで、下記のソフトに行き着くわけで。

Developer Resource: View State Decoder

なんか使い勝手がそれほど良くなかった記憶が。


あと、問題に関係ありそうだった URL のメモ。
自前で ViewState に登録する処理を実装する方法、みたいな感じと。

ASP.netの Webフォームコントロールの値保持について - ITプロフェッショナル部 > dotNetについて


■スクロール処理

今回の要件で、
(1) 入力エラーがあった場合は、その INPUT 要素の辺りにスクロール
(2) DataGrid に項目追加する際、追加されたアイテムを最上部に表示
とかありました。

Find position

この辺を参考に、JavaScript の関数作って対処しました。

まず (1) のほう。対象のエレメントをページの最上部に。

function showElemTop(obj)
{
var curleft = 0;
var curtop = 0;

if (obj.offsetParent) {
while (obj.offsetParent)
{
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
obj = obj.offsetParent;
}
}
else if (obj.x) {
curleft += obj.x;
curtop += obj.y;
}

window.scrollTo(curleft, curtop)
}

次に (2) のほう。対象のスクロール可能な領域の先頭に移動する処理。
今回の場合、DataGrid のスクロールを

@IT:.NET TIPS [ASP.NET]DataGridコントロールにスクロールバーを付けるには? - Webフォーム

この方法で実装したんですが、こんなときに使用。
たぶん IE でしか動作しないけど、管理画面用だから問題なし。

function scrollElemTop(obj)
{
var curleft = 0;
var curtop = 0;

if (obj.offsetParent) {
while (obj.offsetParent)
{
if (obj.style.overflow == "auto") {
break;
}
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
obj = obj.offsetParent;
}
}

if (obj.style.overflow == "auto") {
obj.scrollTop = curtop;
}
}


SmartNavigation のリンク先にも書いてありますが、これを動作させる時は Response.Write() とかやっちゃダメで、Page.RegisterStartupScript を使います。

Page.RegisterStartupScript Method

で、渡すアイテムが変化するので、script の生成は追加処理部で、RegisterStartupScript() は PreRender に書きました。この辺を参考に。

RegisterStartupScriptで書き出されたスクリプトの削除 - GotDotNet Japan 掲示板
posted at 21:15:53 on 2005-12-18 by miau - Category: Work No Trackbacks - Permalink

TrackBack

このエントリにトラックバックはありません
現在トラックバックは受け付けていません。

Comments

ma wrote:

> 今回の場合、DataGrid のスクロールを
こんな方法があったんですね。
stylesheet で対応した記憶が。
2005-12-21 23:20:32

miau wrote:

> stylesheet で対応した記憶が。
これってどんな方法ですか?
Flow Layout Panel を使う方法だとヘッダ部までスクロールされてしまうので、見た目があまり良くないんですけど…解決できたりしますかね?
2005-12-22 00:29:06

Add Comments

現在コメントは受け付けていません。
お手数ですが、 こちら のコメント欄にでも記載していただければと思います。