こんにちは。エンジニアの片岡です。
いつもはCSSの記事ばかり書いているのですが、業務内で困ったことがあり、調べて対応したのでそちらについて書こうと思います。
かなりニッチな内容となってしまいますがよろしくお願いします。
最初に
今回詰まったところはタイトル通りなのですが、UpdatePanelとjQueryで制御している部分で起きた問題について状況はこんな感じです。
- UpdatePanelを使って、Formのinputの変更に合わせてバリデータをかけ表示を更新している
- JavaScriptでページの初期化時に、Fromのinputに対してblurイベントなどを設定している
- 上記の状況において、UpdatePanelが更新されるとblurイベントが効かなくなってしまう
考察
まずはなぜ動かなくなってしまったかの考察から始めます。
おそらく動かなくなっているのはUpdatePanelが更新された際に再描画が走るので、最初のPageLoadでblurイベントを設定したinputとは別のものになってしまっているのだと考えられます。
解決方法として、
・UpdatePanelをやめて全部JavaScriptでやってしまう
なんてことも考えられますが、既存への影響が甚大なので今回はなしとします。
では対策方法としては、
・JavaScriptでUpdatePanelの再描画を検知して、再度blurイベントを設定しなおす
がよさそうです。
実装
この記事のタイトルにもなっている、「どうやってJavaScriptでUpdatePanelの再描画を検知するか」に帰ってきました。
結論から言いますと、「PageRequestManager」を利用します。
PageRequestManagerはUpdatePanelコントロールで発生した非同期通信を管理するための機能を提供するクラスです。
- initializeRequest:非同期ポストバックの初期化時
- beginRequest:非同期ポストバック開始時
- pageLoad:非同期ポストバックの応答取得時(ページ反映前)
- pageLoaded:非同期ポストバックの応答取得時(ページ反映後)
- endRequest:非同期ポストバック完了時
の各タイミングで処理を差し込むことができます。
具体的なコードは下記のとおりです。
// PageRequestManagerのインスタンスを作成
var manager = Sys.WebForms.PageRequestManager.getInstance();
// 非同期ポストバックの初期化時にイベントを登録
manager.add_initializeRequest(
function(sender, args) {
// 行いたい処理
}
);
わかってしまえば簡単ですね。
先ほどのコードをpageLoadの中にでも書いておけばOKです。
さて、利用例がわかったところで今回の目的に合ったものを作成していきます。
今回は「JavaScriptでUpdatePanelの再描画を検知して、再度blurイベントを設定しなおす」ということで、ポストバック終了後にセットする処理を入れましょう。
function pageLoad() {
// 画面初期化時にイベントをセット★
setBlurEvent();
// PageRequestManagerのインスタンスを作成☆
var manager = Sys.WebForms.PageRequestManager.getInstance();
// 非同期ポストバック完了後にイベントを再セット☆
manager.add_endRequest(
function(sender, args) {
setBlurEvent();
}
);
}
こうなりました。
元々は★の部分しかなかったので、☆の部分を追加した感じですね。
これで動作確認をすると、UpdatePanelの更新時にしっかりとsetBlurEvent()が呼ばれていました。
最後に
今回はUpdatePanelの更新が考慮できていないバグについて、バグ改修完了までの考え方や、実際に直した方法を紹介してきました。
調べてもなかなかこれだ!という記事が出てこず、一部の層に需要がありそうだと考えたため、忘備録も兼ねています。
技術が直接役に立たなかったとしても、うまく動かないときの解決に向けた考え方など、少しでも読んでいただいた方の参考になれば幸いです。
コメント