惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
A
About on SuperTechFans
博客园 - Franky
Engineering at Meta
Engineering at Meta
Recent Announcements
Recent Announcements
云风的 BLOG
云风的 BLOG
B
Blog
Microsoft Security Blog
Microsoft Security Blog
L
LangChain Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
Martin Fowler
Martin Fowler
Y
Y Combinator Blog
Stack Overflow Blog
Stack Overflow Blog
博客园 - 叶小钗
Vercel News
Vercel News
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
Last Week in AI
Last Week in AI
腾讯CDC
Microsoft Azure Blog
Microsoft Azure Blog
爱范儿
爱范儿
V
V2EX
G
Google Developers Blog

博客园 - 深夜

AMIS中的组件添加图标的一些注意点。 同一个浏览器多次请求竟然发现是串行执行的,见鬼了。 VSCode 运行go test显示打印日志 现在CSDN真的很讨厌,百度出来都是一堆CSDN的东西。 VScode中的golang代码规范太严格,怎么处理。 chromedp自动启动为headless模式 chromedp下载文件的方法,备忘一下。 vue项目里的日期格式化(摘录) 深入分析 Java 中的中文编码问题 tomcat作为windows服务的参数配置,特别是PermSize的设置 webwork和spring多配置文件的方法 - 深夜 - 博客园 webwork的interceptor来实现ajax功能(buffalo) 用C#实现BHO(Brower Helper Object) 用Sitemesh控制页面布局 关于WebWork2中的中文问题 tomcat中的几点配置说明 使用Filter实现静态HTML缓冲(一种折中方法) 关于DirectX中的DirectShow介绍 基于Delphi的VFW视频捕获程序的开发
高亮显示web页表格行
深夜 · 2010-11-17 · via 博客园 - 深夜

[关键词]:javascript . css . Web标准 . 浏览器兼容 . DOM . 冒泡事件 . 高亮表格行

[摘要]:本文从简单的css高亮显示表格的某一行说开去,探讨了在不同浏览器下对于高亮功能的兼容性。阐述针对表格本身绑定javascript事件实现这一功能的方法。

本篇作为开发学习笔记之一。

[文]

        在web开发中经常遇到需要加亮鼠标指向的表格行的情况。首先说说一般的情况。

        ·简单尝试

        CSS2中允许我们对HTML元素使用hover伪类,这极大的方便了对于表格的样式的控制。

        我们从一个小例子开始:

        XHTML(只列出了表格部分,请自行补完页面,本例在Transational的DTD下通过):
    <table class="datatable" cellspacing="0">
    <thead>
        <tr>
            <th>Item</th>
            <th>Value</th>             
        </tr>
    </thead>
    <tbody>
      <tr class="oddRow">
            <td>项目Item1</td>
            <td>值Value1</td>
      </tr>
      <tr class="evenRow">
            <td>项目Item2</td>
            <td>值Value2</td>
      </tr> 
        <tr class="oddRow">
            <td>项目Item3</td>
            <td>值Value3</td>
        </tr>
        <tr class="evenRow">
            <td>项目Item4</td>
            <td>值Value4</td>
        </tr>
        <tr class="oddRow">
            <td>项目Item5</td>
            <td>值Value5</td>
        </tr> 
        <tr class="evenRow">
            <td>项目Item6</td>
            <td>值Value6</td>
        </tr>   
    </tbody>
    </table>

    然后用CSS定义了表格的样式:

.datatable{
margin:15px auto;
width:500px; /*这两行可以根据需要修改,仅为示例*/
}
.datatable,.datatable tr,.datatable td,.datatable th,.datatable .tableheader td{
border:1px #0073ac solid;
border-collapse:collapse;
padding:3px;
}
.datatable .tableheader td,.datatable th{
font-weight:bold;
background:#fff url(images/thead.png) repeat-x;
padding:8px 5px;
}
.datatable tr:hover{
background-color:#cfe9f7;
}

        对于css的部分,不做过多解释。请注意最后加粗的部分,对tr元素应用了伪类hover的样式。这在对CSS2支持的浏览器下(IE7+,FF,Opera,Safari等)运作的十分完美。然而CSS1仅提供对于锚元素a的伪类支持,遗憾的是IE6仍然只支持CSS1的伪类。于是我们要进行修改,提供对于IE6的支持。

        首先增加一个样式:

.datatable .trHover,.datatable tr:hover{
background-color:#cfe9f7;
}

        此处增加了一个trHover的类,用以修正IE6下的显示。接下来就是书写javascript了。最初的想法非常简单,你不是要鼠标指向时高亮当前行么?于是就对每一行应用javascipt呗。首先写一个javascript的函数。为了统一我把加亮和撤销加亮合并到一个函数中了,这样就可以简化函数调用,对tr的mouseover和mouseout事件绑定一个函数就行了。

function highlightTr(o){
var regStr=/\b\s*trHover\b/g; /*正则表达式过滤trHover类*/
if(o.className.indexOf('trHover')==-1)
    o.className+=" trHover";
else
    o.className=o.className.replace(regStr,"");
}

        这里用到一个小技巧:正则表达式替换。因为你的tr元素可能有其他样式(类)——比如本例的evenRow和oddRow,所以不能简单的在撤销高亮时把对象的className置空。然后就如大家想象的,给tr绑定事件吧:
      <tr class="oddRow" onmouseover="highlightTr();" onmouseout="hightlightTr();">
            <td>项目Item1</td>
            <td>值Value1</td>
      </tr>

        给所有的tr写上事件绑定就可以了。然而这样做也有问题:1、增加了页面的代码量。2、如果表格是由后台服务端程序输出的,有时不允许你给tr元素绑定javascript函数。怎么办?直接的想,可以用js在页面某范围里搜索该样式的表格,然后绑定tr的事件。不过我们今天换个思路,直接对table元素绑定js事件,实现对某一行的高亮!

        这种想法是有根据的。这不得不说说浏览器的事件模型。由于历史原因,各种浏览器在实现javascript事件响应上有差异,然而基本思路还是一致的。js事件在W3C DOM中被描述成捕获-冒泡模型。简单的说有点像下饺子,饺子逐渐沉到锅底,接受了热传递,慢慢漂到上面。回到模型本身,javascript事件有两大类,首先从最外层的元素捕获事件,逐渐向内传递到触发事件的元素——这叫事件捕获,然后再逐渐向外扩展到外层元素——这叫做事件冒泡。IE的实现不支持捕获类型的事件,对冒泡型事件的实现与W3C DOM标准也略有区别,但总体思路是一样的。

        说了半天,我们这次就是想用事件的冒泡处理机制来达到高亮表格行的目的。
        再次重申,冒泡事件是从触发javascript事件的最内层元素扩散到外层的,就像石子激起的涟漪一样。鼠标滑过某一行,首先最内层元素比如td里的文本或者其他元素触发mouseover,接下来传到td-->tr-->tbody-->table依次响应mouseover事件,鼠标移出时,也有这种依次冒泡的过程。这就是我们这样处理事件响应程序的根据。
        首先,我们需要修改XHMTL中的事件绑定代码。去掉tr元素中mouseover和mouseout的事件处理,随后给table加上事件处理。最后表格变成这样:

    <table class="datatable" cellspacing="0" onmouseover="highlightTr();" onmouseout="highlightTr();">
    <thead>
        <tr>
            <th>Item</th>
            <th>Value</th>             
        </tr>
    </thead>
    <tbody>
      <tr class="oddRow">
            <td>项目Item1</td>
            <td>值Value1</td>
      </tr>
      <tr class="evenRow">
            <td>项目Item2</td>
            <td>值Value2</td>
      </tr> 
        <tr class="oddRow">
            <td>项目Item3</td>
            <td>值Value3</td>
        </tr>
        <tr class="evenRow">
            <td>项目Item4</td>
            <td>值Value4</td>
        </tr>
        <tr class="oddRow">
            <td>项目Item5</td>
            <td>值Value5</td>
        </tr> 
        <tr class="evenRow">
            <td>项目Item6</td>
            <td>值Value6</td>
        </tr>   
    </tbody>
    </table>
        和最初我们写的表格相比,只多了table元素的js事件绑定。接下来就是给我们的hightlightTr函数做个大手术了!这里先把最终的代码贴出来然后一起分析:
<script type="text/javascript">
//<!-[CDATA[
//该函数修正IE6不能识别TR元素hover伪类的bug
function highlightTr(){
var theEvent=window.event||arguments.callee.caller.arguments[0];
var srcElement = theEvent.srcElement;
if (!srcElement)
{
    srcElement = theEvent.target;
}
if(!srcElement.parentNode) return false;
var o=srcElement.parentNode;
while(o.parentNode&&o.tagName!="TR")
{
    if(o.tagName=="TABLE") break;
    else o=o.parentNode;
}
var regStr=/\b\s*trHover\b/g;
if(o.className.indexOf('trHover')==-1)
    o.className+=" trHover";
else
    o.className=o.className.replace(regStr,"");
}
//]]>
</script>

        修改后的hightlighTr的版本的思路是这样的:1、处理事件,获得触发javascript事件的页面元素。2、寻找它的父节点,直到找到tr。3、进行样式处理。

       值得说的就是获得触发事件元素的部分考虑了浏览器兼容性。IE的事件模型里window对象有一个event属性,而W3C DOM标准event对象必须作为唯一参数传给事件处理函数,于是它便存在于函数的一个隐藏的参数(在参数列表第0个)里。接下来就是防止异常的一些判断之类的了。最终实现还是由修改元素样式表来完成。

至此整个兼容不同浏览器的高亮表格行的旅行结束了(好长的定语-口-)。很好玩吧~  文中难免疏漏差错,如果对本文有建议或意见欢迎批评指正~  ^_^