使用箭头(上/下)键进行 GridView 行导航






4.88/5 (36投票s)
本文介绍如何使用 JavaScript 借助箭头(上/下)键来导航 GridView 行。
引言
在 IE 中使用箭头(上/下)键实现 GridView
行导航是一项简单的任务,但在其他浏览器中则有些棘手。最初,我编写的 JavaScript 代码在 IE 中运行良好,但在其他浏览器中却不行。在网上进行了大量研究后,我从 Mozilla Development Center 网站 [^] 学到了一些技巧,以便让此脚本在其他浏览器上运行。
使用此脚本,您可以使用箭头(上/下)键导航 GridView
行,但导航之前,您必须先使用鼠标 onclick
事件选择一行。
HTML 代码
以下是此演示中 GridView
的 HTML 代码
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False"
OnRowCreated="gridView_RowCreated"
TabIndex="0" GridLines="Horizontal">
<Columns>
<asp:BoundField HeaderText="S#" DataField="sno">
<HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="50px" />
<ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="50px" />
</asp:BoundField>
<asp:BoundField HeaderText="Random No" DataField="rndno">
<HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="150px" />
<ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="150px" />
</asp:BoundField>
<asp:BoundField HeaderText="Date" DataField="date">
<HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="100px" />
<ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="100px" />
</asp:BoundField>
<asp:BoundField HeaderText="Time" DataField="time">
<HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="100px" />
<ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="100px" />
</asp:BoundField>
</Columns>
<RowStyle BackColor="#FFE0C0" />
<HeaderStyle BackColor="#FF8000" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="#FFC080" />
</asp:GridView>
在此演示中,GridView
的行为方式如同一个 TabIndex
等于 0 的组件。
C# 代码
以下是 GridView
的 RowCreated
事件的 C# 代码
if (e.Row.RowType == DataControlRowType.DataRow &&
(e.Row.RowState == DataControlRowState.Normal ||
e.Row.RowState == DataControlRowState.Alternate))
{
e.Row.TabIndex = -1;
e.Row.Attributes["onclick"] =
string.Format("javascript:SelectRow(this, {0});", e.Row.RowIndex);
e.Row.Attributes["onkeydown"] = "javascript:return SelectSibling(event);";
e.Row.Attributes["onselectstart"] = "javascript:return false;";
}
在上面的代码中,首先确保该行是 Normal
或 Alternate
。然后,在 GirdView
的每一行上附加了客户端事件 onclick
、onkeydown
和 onselectstart
。另外,请注意,GirdView
的每一行都已设置为 TabIndex
等于 -1,以便以编程方式将焦点设置在其上。实际上,在此示例中,GridView
的行为方式如同一个 TabIndex
= 0 的组件,而 GridView
的每一行则表现得像组件中 TabIndex
= -1 的元素。通过箭头键进行组件中每个元素的导航。当用户通过箭头(上/下)键导航到某一行时,该行就会获得焦点。通过在 GridView
的每一行上关联 onkeydown
事件来实现对箭头键的支持。
在捕获按键事件时,重要的是阻止浏览器执行按键的默认行为。按下向上/向下箭头键产生的常见浏览器行为是滚动文档。如果您希望捕获箭头键并使用它们将焦点更改到不同的 GridView
行,则需要阻止默认的滚动行为。这可以通过将事件的返回值设置为 false
来实现。请注意 onkeydown
事件是如何在行上附加的。
onclick
事件用于通过鼠标选择一行。在使用箭头(上/下)键导航 GridView
行之前,我们必须先使用鼠标 onclick
事件选择一行。
onselectstart
事件用于在使用鼠标选择 GridView
行时,阻止单元格文本被选中。
JavaScript代码
<script type="text/javascript">
var SelectedRow = null;
var SelectedRowIndex = null;
var UpperBound = null;
var LowerBound = null;
window.onload = function()
{
UpperBound = parseInt('<%= this.gridView.Rows.Count %>') - 1;
LowerBound = 0;
SelectedRowIndex = -1;
}
function SelectRow(CurrentRow, RowIndex)
{
if(SelectedRow == CurrentRow || RowIndex > UpperBound || RowIndex < LowerBound)
return;
if(SelectedRow != null)
{
SelectedRow.style.backgroundColor = SelectedRow.originalBackgroundColor;
SelectedRow.style.color = SelectedRow.originalForeColor;
}
if(CurrentRow != null)
{
CurrentRow.originalBackgroundColor = CurrentRow.style.backgroundColor;
CurrentRow.originalForeColor = CurrentRow.style.color;
CurrentRow.style.backgroundColor = '#DCFC5C';
CurrentRow.style.color = 'Black';
}
SelectedRow = CurrentRow;
SelectedRowIndex = RowIndex;
setTimeout("SelectedRow.focus();",0);
}
function SelectSibling(e)
{
var e = e ? e : window.event;
var KeyCode = e.which ? e.which : e.keyCode;
if(KeyCode == 40)
SelectRow(SelectedRow.nextSibling, SelectedRowIndex + 1);
else if(KeyCode == 38)
SelectRow(SelectedRow.previousSibling, SelectedRowIndex - 1);
return false;
}
</script>
在上面的脚本中,全局变量已在 window.onload
事件中初始化。有两个函数:SelectRow
和 SelectSibling
。当我们在 GridView
行上单击时,或者通过 keydown
或 keyup
事件响应调用 SelectSibling
方法时,将调用 SelectRow
。当我们按下向上或向下箭头键时,将调用 SelectSibling
方法。此方法会使用适当的参数调用 SelectRow
方法。在 SelectRow
函数中,如果当前行是前一个选定的行,或者 RowIndex
不在 LowerBound
和 UpperBound
之间,则不执行任何操作;否则,它会恢复前一个选定行的状态,并更改当前选定行的状态。之后,变量 SelectedRow
和 SelectedRowIndex
的值会相应更改,并使用 setTimeout
方法将焦点设置到当前选定的行上。在 IE 和 Mozilla 中都需要此超时,以防止用户单击按钮和其他控件时,脚本出现意外的异常行为。
结论
我已尽最大努力使此代码无错误。非常欢迎对代码提出进一步改进的建议和批评。
浏览器兼容性
我已在各种浏览器上测试过此代码,运行效果良好。下面是测试过的浏览器及其版本的列表
此代码目前在 Opera(9.27 的早期版本)、Safari、Firebox(1.0 版本)以及 Mozilla 的旧版本(1.7 及更早版本)上可能无法正常工作,因为某些浏览器不支持对所有元素都支持的 TabIndex
属性等新功能。