非同期ポストバック中にフォーカスされた要素を保存するための小さなスクリプトを作成しました。完全ポストバック内でコントロールをタブで移動すると、いくつかの不思議な理由のためにがトリガーされます。ここには、作業するための簡潔なサンプルがあります:ASP.NETウェブフォームポストバックの挙動を妨げる
<%@ Page Language="C#" EnableEventValidation="false" %>
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<script runat="server">
public IEnumerable<int> Measurements_GetData()
{
return new[] { 123, 328, 1099 };
}
</script>
</head>
<body>
<form method="post" runat="server">
<asp:ScriptManager runat="server" />
<asp:UpdatePanel runat="server">
<ContentTemplate>
<h1>OK</h1>
<div>
<asp:TextBox ID="Measurement1" runat="server" Text="123" AutoPostBack="true" />
</div>
<div>
<asp:TextBox ID="TextBox1" runat="server" Text="328" AutoPostBack="true" />
</div>
<div>
<asp:TextBox ID="TextBox2" runat="server" Text="1099" AutoPostBack="true" />
</div>
<h1>Not OK</h1>
<asp:Repeater ID="Measurements" runat="server" SelectMethod="Measurements_GetData" ItemType="System.Int32">
<ItemTemplate>
<div>
<asp:TextBox ID="Measurement" runat="server" AutoPostBack="true" Text="<%# Item %>" />
</div>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
</form>
<script type="text/javascript">
(function() {
var focusedElementId = "";
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(function (source, args) {
// re-focus element, if any selected prior to postback
if (focusedElementId !== "") {
document.getElementById(focusedElementId).focus();
console.log("focus:" + focusedElementId);
}
});
prm.add_pageLoading(function (source, args) {
var fe = document.activeElement;
focusedElementId = fe !== null ? fe.id : "";
});
})();
</script>
</body>
</html>
このサンプルは、動作中と動作していない両方の動作を示しています。最初のテキストボックスをクリックすると、値を変更し、次のタブに移動し、値を変更し、次のタブに移動します。最後の要素にフォーカスが維持され、JSコンソールで保存された要素の進行が確認できます。
あなたがJSコンソールを見て、リピータで生成されたマークアップ(Not OKセクション)の最初のテキスト入力をクリックして、タブを変更してから、タブをもう一度変更すると、最後のコントロールでフォーカスが失われていることがわかります。完全なポストバックがトリガーされます(JSコンソールはクリアされます)。
ここでは何が起こっていますか?これはWebフォームのバグでなければならないように見えますが、それ以外の場合はわかりません。バグの場合、回避策はありますか?
もちろん、スクリプトなしでも動作しますが、それはこの質問のポイントです。私はJSのテキストボックスをバインドしたり、何か特別なことはしません。 page_Loadingイベントは、非同期応答が受信されると起動し、現在フォーカスされている要素のidが保存されます。次に、page_Loadedイベントが発生します(要求された最初の読み込み時にのみ) idで呼び出してfocus()を呼び出します。私は何もキャッシュしない、私は常にidによってコントロールを調べる。ここには何も特別なことはありません。それは不合理な単純なスクリプトです。回避策をありがとうございますが、これはバグではありません。 – naasking