用javascript/css实现GridView行背景色交替、点击行变色

前几天在博问里发现有人问关于 GridView点击行变色 的问题,突然想起很久很久以前,写过一篇文章 一个简单但常用的表格样式--鼠标划过行变色--简洁实现 ,是关于表格行颜色交替和鼠标指向时变色的,正好今天把那一篇补充和扩展一下,加上鼠标点击选择(其实只是点击后变个颜色,“选择”这个词在这里不合适),顺便把这个直接应用到GridView上,如果是其他的控件,或者直接的HTML,稍加修改也可以用上,这里仅提供一个思路。虽然GridView使用AlternatingRowStyle提供了交替行背景色的问题,但这个东西用着实在不爽,看它生成到HTML的那个table,那叫一个乱啊。

下面是代码,注释应该还算比较详细,比较适合初学者,可以把下面两个文件的代码直接复制到你的项目中直接执行。最下面有文件的下载地址,也可以直接下载后运行,代码在IE7和Firefox2下测试通过,有任何问题,请在下面留言,我将尽量及时回复。

BackgroundColor.aspx
主要包含一个GridView,是我们折腾的重点对象,还有一堆javascript,是我们折腾GridView的手段

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="BackgroundColor.aspx.cs" Inherits="_BackgroundColor" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>BackgroundColor</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:GridView runat="server" ID="gvMeiMingZi"></asp:GridView>
    </form>
    <script type="text/javascript">
        //把事件放在onload里,因为我不知道JS如果直接写到这儿是不是会等页面加载完才执行
        //使用<%=%>方式输出GridView的ID是因为某些情况下(如使用了MasterPage)会造成HTML中ID的变化
        //颜色值推荐使用Hex,如 #f00 或 #ff0000
        window.onload = function(){
            GridViewColor("<%=gvMeiMingZi.ClientID%>","#fff","#eee","#6df","#fd6");
        }
       
        //参数依次为(后两个如果指定为空值,则不会发生相应的事件):
        //GridView ID, 正常行背景色,交替行背景色,鼠标指向行背景色,鼠标点击后背景色
        function GridViewColor(GridViewId, NormalColor, AlterColor, HoverColor, SelectColor){
            //获取所有要控制的行
            var AllRows = document.getElementById(GridViewId).getElementsByTagName("tr");
           
            //设置每一行的背景色和事件,循环从1开始而非0,可以避开表头那一行
            for(var i=1; i<AllRows.length; i++){
                //设定本行默认的背景色
                AllRows[i].style.background = i%2==0?NormalColor:AlterColor;
               
                //如果指定了鼠标指向的背景色,则添加onmouseover/onmouseout事件
                //处于选中状态的行发生这两个事件时不改变颜色
                if(HoverColor != ""){
                    AllRows[i].onmouseover = function(){if(!this.selected)this.style.background = HoverColor;}
                    if(i%2 == 0){
                        AllRows[i].onmouseout = function(){if(!this.selected)this.style.background = NormalColor;}
                    }
                    else{
                        AllRows[i].onmouseout = function(){if(!this.selected)this.style.background = AlterColor;}
                    }
                }

                //如果指定了鼠标点击的背景色,则添加onclick事件
                //在事件响应中修改被点击行的选中状态
                if(SelectColor != ""){
                    AllRows[i].onclick = function(){
                        this.style.background = this.style.background==SelectColor?HoverColor:SelectColor;
                        this.selected = !this.selected;
                    }
                }
            }
        }
    </script>
</body>
</html>

BackgroundColor.aspx.cs
用于生成一堆用于测试的数据,不然前面的GridView里啥也没有,就看不出效果了

using System;
using System.Data;

public partial class _BackgroundColor:System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //生成DataTable并添加10个列
        DataTable dt = new DataTable();
        for(int i = 0; i < 10; i++)
        {
            dt.Columns.Add();
        }

        //往DataTable里添加20行数据
        for(int i = 0; i < 20; i++)
        {
            dt.Rows.Add(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
        }

        //将DataTable绑定到GridView
        gvMeiMingZi.DataSource = dt;
        gvMeiMingZi.DataBind();
    }
}

示例文件:点击这里下载示例文件

版权声明:本文原创发表于博客园,作者为丁学
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
posted @ 2008-05-19 07:43 丁学 阅读(4242) 评论(21)  编辑 收藏 所属分类: ASP.NETWEB技术

  回复  引用  查看    
#1楼 2008-05-19 08:24 | 蜗牛身上的一只蚂蚁      
点击后,鼠标移开。选取的怎么没有回到原来的颜色啊。
  回复  引用  查看    
#2楼 2008-05-19 08:33 | 汉城      
先收藏 有时间再看
  回复  引用  查看    
#3楼 [楼主]2008-05-19 08:34 | 丁学      
@蜗牛身上的一只蚂蚁
选中了,当然就不会回到原来的颜色喽,要的就是这个效果,不然“选择”就没有意义了,再点一下就可以取消选择
  回复  引用  查看    
#4楼 2008-05-19 08:37 | 蜗牛身上的一只蚂蚁      
可是选着一行后,然后再选别的。就好象一大片一样啊。
  回复  引用  查看    
#5楼 2008-05-19 08:39 | 蜗牛身上的一只蚂蚁      
我的意思是。选中一行后,选别的行。前面选的那一行变回没选中的状态。。后面选的才是选中状态。。。谢谢。能否实现呢。。。
  回复  引用  查看    
#6楼 [楼主]2008-05-19 09:39 | 丁学      
@蜗牛身上的一只蚂蚁
嗯......可以的
一个方法是在点击时遍历所有行,把背景全部恢复,然后再把当前选择的行着色
另一个方法是定义一个变量存放当前选中的行,在点击另一行时,只恢复变色的那一行,不过这样就只能选择一行了
两个办法实现起来都不难,只是我感觉保留这个多选功能还是很必要的
  回复  引用  查看    
#7楼 2008-05-19 09:41 | 蜗牛身上的一只蚂蚁      
呵呵。谢谢。请问一下这这个多选功能在什么时候用呢?用了干什么呢?
  回复  引用  查看    
#8楼 [楼主]2008-05-19 09:51 | 丁学      
@蜗牛身上的一只蚂蚁
你可以看这一篇:
http://www.cnblogs.com/dingxue/archive/2008/05/19/1202305.html
这个多选其实是想用来代替这篇里的CheckBox,只是我没有在这里实现选择行的值的提取
如果要实现,其实也简单,在设置行默认背景色时给行再加一个property,值就取本行的标识列,这样就可以轻易在点击时获取到选中行的标识,或者可以干脆就在选择行时,读取这个行的标识列值(这里是第一列)
  回复  引用  查看    
#9楼 2008-05-19 09:53 | 蜗牛身上的一只蚂蚁      
呵呵。嗯。明白了。谢谢。。。
  回复  引用    
#10楼 2008-05-19 12:58 | 金鱼[morningwang] [未注册用户]
我说 哪些你给我怎么不能变回来原来的颜色呀?
原来这个本身就是这样设计的呀?
上次忘说需求了: 我们点击的是电视节目的列表在中间位置是一个播放器,说以,只需要一个就可以了。 呵呵
不过,现在问题已经解决了。 还得谢谢大家的帮助。
  回复  引用  查看    
#11楼 [楼主]2008-05-19 13:11 | 丁学      
@金鱼[morningwang]
汗~~~~~白写了~~~~~~~~~~~~~~~~~
  回复  引用  查看    
#12楼 2008-05-19 16:42 | chenglingr      
佩服,学习中
  回复  引用  查看    
#13楼 2008-05-19 20:47 | JackLee      
cs代码不也能实现吗?为什么不用cs实现呢!
  回复  引用  查看    
#14楼 [楼主]2008-05-19 23:02 | 丁学      
@JackLee
AlternatingRowStyles可以实现交替行,但无法实现行变色,行变色依然要生成javascript来实现
而且CS生成交替行时会把style或class写到每个td或tr上,代码会变得长很多,越是大GridView越是明显
除非BT到拿CS输出和上面一样的JS代码
  回复  引用  查看    
#15楼 2008-05-20 09:58 | Clark Zheng      
http://boxover.swazz.org/
可以看看boxover的实现
  回复  引用  查看    
#16楼 2008-05-22 15:23 | datasky      
gridview有分页的时候分页部分的样式也变掉了,怎么办?
  回复  引用  查看    
#17楼 [楼主]2008-05-23 06:40 | 丁学      
@datasky
这个似乎不太好办
如果分页导航在最下面(默认是在最下面,PagerSetting -> Position == Bottom),还是有办法的,给GridView的Pager加个class(其他的也可以,不过这个比较方便),比如:
<PagerStyle CssClass="Pager" />

然后修改下面的JS,在for循环里最靠前的地方加这样一行:
if(AllRows[i].className == "Pager") break;

这里的break就是为结束循环,而并不是为了跳过当前行,因为在出现这个Pager行之后,还有一个tr被get到了,就是Pager里自动生成的那个table里的tr,所以直接跳出去了,也导致这个方法仅限用于分页栏在最下面的情况

在上面或者上下都有的,我得再想想
  回复  引用  查看    
#18楼 2008-06-17 09:23 | asp.net2.0      
楼主你这样写不是每张页面都需要复制粘贴这段js代码 没想过要做的更灵活点吗 把这段js发到js文件里面 通过调用 传递gridview id号?
  回复  引用  查看    
#19楼 [楼主]2008-06-17 11:15 | 丁学      
@asp.net2.0
当然不需要在每个页面都复制一份,做的时候考虑了这个问题,可以把GridViewColor()的实现放到JS中,页面中调用是这一行:
window.onload = function(){
GridViewColor("<%=gvMeiMingZi.ClientID%>","#fff","#eee","#6df","#fd6");
}

第一个参数是GV的ID,你甚至可以为一个页面的多个GV定义不同的样式,只需要修改ID对应的调用的其他几个参数
  回复  引用  查看    
#20楼 2008-06-25 15:58 | 求知无傲      
飘过。

  回复  引用    
#21楼 2008-07-07 14:08 | 72color [未注册用户]
先收藏了,我一直很讨厌GridView的说
呵呵!

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-05-19 08:01 编辑过
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接: