【发布时间】:2017-01-17 15:13:54
【问题描述】:
我创建了一个小脚本来在异步回发期间保留焦点元素,并且在通过在 asp:Repeater 中生成的控件时,它工作得非常好除了,其中 完整的回发 出于某种神秘的原因被触发。这是一个简洁的示例:
<%@ 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>
此示例显示了工作和非工作行为。如果单击第一个文本框,更改值,tab 到下一个,更改值,tab 到下一个,它正确地将焦点保留在最后一个元素上,您可以在 JS 控制台中看到保留的焦点元素的进度。
现在,如果您观看 JS 控制台并单击中继器生成标记(Not OK 部分)中的第一个文本输入,然后更改选项卡,再次更改选项卡,您可以看到焦点丢失在最后一个控件上,因为一个完整的回发被触发(JS 控制台被清除)。
这里发生了什么?这看起来一定是网络表单错误,否则我无法理解。如果是错误,是否有解决方法?
【问题讨论】:
标签: javascript asp.net webforms