65.9K
CodeProject 正在变化。 阅读更多。
Home

在 GridView 行上实现悬停延迟

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.03/5 (41投票s)

2009年5月12日

CPOL

3分钟阅读

viewsIcon

69383

downloadIcon

602

本文介绍如何为GridView行实现悬停延迟以处理点击事件。

HoverDelay.gif

引言

在本文中,我将介绍一种在GridView行上实现悬停延迟功能以处理click event的方法。

背景

在最近的一个项目中,我的客户希望实现悬停延迟,以避免对GridView行的意外点击。实际上,在这个项目中,项目显示在GridView中,并且有一个通过弹出窗口编辑每个项目的_功能。弹出窗口是通过单击GridView行打开的。因此,客户要求用户在点击激活弹出窗口以在GridView行上打开弹出窗口之前,将鼠标悬停在项目上 1 秒。当用户将鼠标悬停在项目上 1 秒后,该项目会以不同的背景颜色突出显示,以表明用户现在可以点击进行编辑。也就是说,在将鼠标悬停在项目上 1 秒之前,点击不应处于活动状态。换句话说,如果用户在GridView行上花费 1 秒之前单击某个项目,则不应打开弹出窗口来编辑特定项目。这就是所谓的悬停延迟。因此,我开始深入研究这个问题,并最终得出了以下解决方案。

CSS 代码

我为此演示使用了四个 CSS 类 - Header类用于GridViewHeader行,RowAlternateRow类分别用于GridViewNormalAlternate行。HoverDelay类用于在mouseover event上更改GridView行(NormalAlternate)的外观。

.Header
{
    background-color:DarkOrange;
    color:White;
    font-weight:bold;
    text-align:center;
    vertical-align:middle;
}

.Row
{
    background-color:Moccasin;
    color:Black;
    text-align:center;
    vertical-align:middle;
    cursor:default;
}

.AlternateRow
{
    background-color:#FFCC66;
    color:Black;
    text-align:center;
    vertical-align:middle;
    cursor:default;
}

.HoverDelay
{
    background-color:White;
    color:Black;
    font-weight:bold;
    text-align:center;
    vertical-align:middle;
    cursor:hand;
}

我将这些 CSS 类放在一个单独的*StyleSheet.css*文件中,并在*Default.aspx*页面中附加了它的引用,如下所示:

<link href="CSS/StyleSheet.css" rel="stylesheet" type="text/css" />

HTML 代码

以下是GridView的 HTML 代码。我在GridViewRowStyleAlternatingRowStyleHeaderStyle中分别应用了RowAlternateRowHeader CSS 类。

<asp:GridView ID="gvHoverDelay" runat="server" AutoGenerateColumns="False"
                               OnRowDataBound="gvHoverDelay_RowDataBound">
  <Columns>
      <asp:BoundField DataField="RandomNo" HeaderText="Random Number">
         <HeaderStyle Width="150px" />
         <ItemStyle Width="150px" />
      </asp:BoundField>
      <asp:BoundField DataField="Date" HeaderText="Date">
         <HeaderStyle Width="75px" />
         <ItemStyle Width="75px" />
      </asp:BoundField>
      <asp:BoundField DataField="Time" HeaderText="Time">
         <HeaderStyle Width="100px" />
         <ItemStyle Width="100px" />
      </asp:BoundField>
  </Columns>
  <RowStyle CssClass="Row" />
  <AlternatingRowStyle CssClass="AlternateRow" />
  <HeaderStyle CssClass="Header" />
</asp:GridView>

附加事件

我通过RowDataBound event在每个GridView行上分别附加了clickmouseovermouseout event,如下所示:

 if (e.Row.RowType == DataControlRowType.DataRow
    && (e.Row.RowState == DataControlRowState.Normal || 
		e.Row.RowState == DataControlRowState.Alternate))
 {
    string CssClass = (e.Row.RowState == DataControlRowState.Normal
                        ? ((GridView)sender).RowStyle.CssClass : 
			((GridView)sender).AlternatingRowStyle.CssClass);
   
    e.Row.Attributes["onmouseover"] = string.Format
                                      {
                                         "javascript:OnHoverDelay(this, '{0}', 
							'HoverDelay');",
                                          CssClass
                                      );

    e.Row.Attributes["onmouseout"] = "javascript:OffHoverDelay(this);";
    e.Row.Attributes["onselectstart"] = "javascript:return false;";
    e.Row.Attributes["onclick"] = "javascript:Click(this);";
 }

GridView行的Mouseover事件

每当我们将鼠标指针放在任何GridView的行(NormalAlternate)上时,都会触发此event。在此event中,首先,当前行的 CSS 类存储在行的自定义属性Class中,然后调用Ready方法。通过 JavaScript setTimeout方法将Ready方法的调用延迟 1 秒。在这里,我使用了 JavaScript 闭包通过某些参数延迟调用Ready方法。

function OnHoverDelay(This, CurrentCSS, HoverCSS)
{  
   This.Class = CurrentCSS;
                    
   TimeOut = setTimeout( function() { Ready(This, HoverCSS); }, 1000);                
}  

GridView行的Mouseout事件

每当我们从任何GridView的行(NormalAlternate)上移开鼠标指针时,就会触发此event。在此event中,首先,如果存在,则通过 JavaScript clearTimeout方法取消对Ready方法的调用延迟。之后,CSS 类会恢复,并且当前GridView行的自定义属性IsReady的值被设置为false

function OffHoverDelay(This)
{
   clearTimeout(TimeOut);
   This.className = This.Class; 
   This.IsReady = false; 
}

GridView行的Click事件

当我们单击任何GridView的行(NormalAlternate)时,都会触发此event。在此event中,如果当前行的自定义属性IsReady的值为true,则会显示alert消息。您可以调用自己的方法而不是调用alert()消息。

function Click(This)
{
   if(This.IsReady)
      alert('Ready to click!!!'); 
}

Ready方法

此方法从OnHoverDelay方法调用。此方法主要用于更改 CSS 类以及将自定义属性IsReady的值设置为true,以指示当前GridView行已准备好进行点击。

function Ready(This, HoverCSS)
{ 
   This.className = HoverCSS; 
   This.IsReady = true; 
} 

我将所有 JavaScript 方法(OnHoverDelayOffHoverDelayClickReady)放在一个单独的*JScript.js*文件中,并在*Default.aspx*页面中附加了它的引用,如下所示:

<script type="text/javascript" src="JS/JScript.js"></script>

总结

所以,这就是我为解决悬停延迟问题而采取的方法。虽然最初我开发悬停延迟是为了在GridView行上 1 秒内禁用click event,但后来我也使用悬停延迟来禁用GridView行的拖放。如果您有其他更好或不同的解决方案,请告诉我。

支持的浏览器

我已在以下浏览器中成功测试了此代码:

Browsers.png

历史

  • 2009年5月26日 -- 文章更新
  • 2009年5月12日 -- 发布原始版本
© . All rights reserved.