高亮显示web页表格行的javascript代码


Posted in Javascript onNovember 19, 2010

本篇作为开发学习笔记之一。
[文]
在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个)里。接下来就是防止异常的一些判断之类的了。最终实现还是由修改元素样式表来完成。
至此整个兼容不同浏览器的高亮表格行的旅行结束了(好长的定语-口-)。很好玩吧~ 文中难免疏漏差错,如果对本文有建议或意见欢迎批评指正~ ^_^
Javascript 相关文章推荐
菜鸟javascript基础资料整理3 正则
Dec 06 Javascript
JQuery触发radio或checkbox的change事件
Dec 18 Javascript
jQuery控制输入框只能输入数值的小例子
Mar 20 Javascript
javascript如何判断输入的url是否正确
Apr 11 Javascript
jQuery中的pushStack实现原理和应用实例
Feb 03 Javascript
EsLint入门学习教程
Feb 17 Javascript
基于VUE.JS的移动端框架Mint UI的使用
Oct 11 Javascript
vue中mint-ui的使用方法
Apr 04 Javascript
vue实现菜单切换功能
May 08 Javascript
JS通过ajax + 多列布局 + 自动加载实现瀑布流效果
May 30 Javascript
详解微信小程序开发之formId使用(模板消息)
Aug 27 Javascript
vue打开新窗口并实现传参的图文实例
Mar 04 Vue.js
javascript tips提示框组件实现代码
Nov 19 #Javascript
突发奇想的一个jquery插件
Nov 19 #Javascript
基于JQuery的访问WebService的代码(可访问Java[Xfire])
Nov 19 #Javascript
基于jQuery的获得各种控件Value的方法
Nov 19 #Javascript
基于jquery实现的可以编辑选择的下拉框的代码
Nov 19 #Javascript
使用jQuery的将桌面应用程序引入浏览器
Nov 19 #Javascript
DIV菜单层实现代码
Nov 19 #Javascript
You might like
PHP开发者常犯的10个MySQL错误更正剖析
2012/01/30 PHP
慎用preg_replace危险的/e修饰符(一句话后门常用)
2013/06/19 PHP
php 强制下载文件实现代码
2013/10/28 PHP
PHP微信公众号开发之微信红包实现方法分析
2017/07/14 PHP
PHP开发实现微信退款功能示例
2017/11/25 PHP
JavaScript中的匀速运动和变速(缓冲)运动详细介绍
2012/11/11 Javascript
js 剪切板应用clipboardData详细解析
2013/12/17 Javascript
jquery中子元素和后代元素的区别示例介绍
2014/04/02 Javascript
JavaScript中匿名函数用法实例
2015/03/23 Javascript
JavaScript中的数据类型转换方法小结
2015/10/26 Javascript
jQuery中的each()详细介绍(推荐)
2016/05/25 Javascript
jQuery插件扩展测试实例
2016/06/21 Javascript
JS及PHP代码编写八大排序算法
2016/07/12 Javascript
vue2.0开发实践总结之疑难篇
2016/12/07 Javascript
JS实现简单的二元方程计算器功能示例
2017/01/03 Javascript
JS实现数组去重复值的方法示例
2017/02/18 Javascript
基于Datatables跳转到指定页的简单实例
2017/11/09 Javascript
vue slot 在子组件中显示父组件传递的模板
2018/03/02 Javascript
React Form组件的实现封装杂谈
2018/05/07 Javascript
用vue快速开发app的脚手架工具
2018/06/11 Javascript
基于JavaScript实现每日签到打卡轨迹功能
2018/11/29 Javascript
浅析JavaScript异步代码优化
2019/03/18 Javascript
layui的表单验证支持ajax判断用户名是否重复的实例
2019/09/06 Javascript
python ip正则式
2009/05/07 Python
python列表list保留顺序去重的实例
2018/12/14 Python
Python实现二维曲线拟合的方法
2018/12/29 Python
Python转换时间的图文方法
2019/07/01 Python
Python 读取xml数据,cv2裁剪图片实例
2020/03/10 Python
浅谈css3中calc在less编译时被计算的解决办法
2017/12/04 HTML / CSS
使用Html5中的cavas画一面国旗
2019/09/25 HTML / CSS
美国高端寝具品牌:Coyuchi
2017/02/08 全球购物
Otticanet英国:最顶尖的世界名牌眼镜, 能得到打折季的价格
2019/02/10 全球购物
什么是Rollback Segment
2013/04/22 面试题
孕妇离婚协议书范本
2014/11/20 职场文书
毕业生评语大全
2015/01/04 职场文书
2016年大学生寒假社会实践心得体会
2015/10/09 职场文书