在很多地方看到鼠标从某个表格上划过时,表格行的背景色会逐渐地变淡直至消失,感觉非常酷。当时看到了也想做一个,可惜我始终不明白是怎么弄的,后来才知道是生成一定数量的渐变色,再使用 JavaScript 的计时器函数,逐一调用,呵呵。
这里主要涉及一些 RGB 渐变的东西,我是这样处理的:将终止颜色的 RGB 各值与起始颜色的 RGB 各值相减,再除以渐变步长,然后再在起始颜色的基本上将各分量逐步加上该步长。
用这种方法做一个 ColorGradient 的类用于产生渐变色的数组。
/** * 色彩渐变 * @param start 起始颜色,使用 # 颜色表 * @param end 终止颜色 * @param step 渐变步长,大于 1 并且小于 200,默认为 16 */ var ColorGradient = function(start, end, step) { this.start = this._toRGB(start); this.end = this._toRGB(end); this.step = (function() { if(!step || step < 1 || step > 200) { return 16; } return step; })(); this.gradient = []; } ColorGradient.prototype = { // 获得渐变的颜色数组,以 6 位十六进制字符串返回 getGradient : function() { return this._getGradient(); }, // 获得所设定的步长值 getStep : function() { return this.step; }, // 测试工作,用于在页面上渐变测试 test : function() { var grad = this._getGradient(); var n = 400 / this.step; var p = document.createElement('div'); for(var i = 0; i < grad.length; i++) { var d = document.createElement('div'); d.className = 'grad'; d.style.width = n + 'px'; d.style.backgroundColor = '#' + grad[i]; p.appendChild(d); } document.body.appendChild(p); }, // 生成渐变色数组 _getGradient : function() { if(this.gradient.length > 0) { // 如果渐变色变量中有值直接返回 return this.gradienth; } // 生成各步的颜色 for(var i = 0; i <= this.step; i++) { var color = this._getNewColor(i).toString(16); while(color.length < 6) { color = '0' + color; } this.gradient.push(color); } return this.gradient; }, // 根据 RGB 变化量获得每步的 RGB 颜色 _getNewColor : function(k) { var rgbStep = this._getStepRgb(); var rgb = 0; for(var i = 0; i < 3; i++) { var c = Math.floor(this.start[i] + rgbStep[i] * k); rgb |= c << ((3 - i - 1) * 8); } return rgb; }, // 获得 RGB 三种颜色的变化量 _getStepRgb : function() { var rgb = []; // 依次获得 R、G、B 的变化步长 for(var i = 0; i < 3; i++) { rgb.push(this._getStepVar(i)); } return rgb; }, // 根据渐变步长、起始、终止颜色获得步长的变化量 _getStepVar : function(index) { return (this.end[index] - this.start[index]) / this.step; }, /** * 将 # 颜色转换成 RGB 颜色数组 * 索引 0 -- 红色 R * 索引 1 -- 绿色 G * 索引 2 -- 蓝色 B */ _toRGB : function(color) { var v = color.substring(1); var c = parseInt(v, 16); var rgb = []; for(var i = 0; i < 3; i++) { rgb.push(c >> ((3 - i - 1) * 8) & 0xff); } return rgb; } }
上面这个ColorGradient
类在生成对象后,调用getGradient()
方法就能获得渐变颜色数组,从开始色到终止色。
为了这完成这个程序,还定义了几个工具类,特别是事件处理类。由于浏览器存在差异,各种浏览器中的事件绑定都不一样,比如 IE 中使用attachEvent
函数,而 Firefox 中则使用addEventListener
这个函数,为了避免这些差异就很有必要构造一些兼容各浏览器的工具方法。
还有一个小问题,在进行事件绑定时,所绑定的事件处理程序只是一个引用,并不能放上参数。比如有handler(str)
方法,要将其绑定在obj
的onclick
事件上,如果使用obj.onclick = handler;
的话,参数没办法传递,如果使用obj.onclick = handler(str);
也不对,这样是把hadnler
执行后的结果给了事件,如果用obj.onclick = 'handler(str)';
这样也是不对的,这样只是把字符串给了事件,那该怎么办呢?
实际上可以通过调用一个方法,这个方法调用后将返回另一个方法引用,这样就能达到我们的目的了。
/** * 事件处理工具类 */ var Event = function(){} Event = { /** * 为 element 使用 handler 处理程序添加至 event 事件 * 兼容 IE 及 Firefox 等浏览器 * * 例如为 botton 对象添加 onclick 事件,使用 clickEvent * 方法作为处理程序: * Event.addEvent(botton, 'click', clickEvent); * * @param element 需要添加事件的对象(Object) * @param event 需要添加的事件名称(String),不加“on” * @param handler 需要添加的方法引用(Function) */ addEvent : function(element, event, handler) { if(element.attachEvent) { element.attachEvent('on' + event, handler); } else if (element.addEventListener) { element.addEventListener(event, handler, false); } else { element['on' + event] = handler; } }, /** * 添加事件处理程序时,只能添加一个方法的引用,并不能给 * 方法加上参数。比如定义了 clickEvent(str) 这个方法,现 * 在要将其作为 obj 的 onclick 的事件处理程序,就可以用: * obj.onclick = Event.getFuntion(null, clickEvent, str); */ getFunction : function(obj, fun) { var args = []; obj = obj || window; for(var i = 2; i < arguments.length; i++) { args.push(arguments[i]); } return function() { fun.apply(obj, args); }; } }
用于表格渐变的代码如下:
/** * 封装了拖影效果的类 * @param id 表格的 id 名 * @param time 各颜色渐变的时间间隔,默认为 10 * @param start 起始颜色,默认为 #dcdcdc * @param end 结束颜色,默认为 #ffffff */ var Table = function(id, time, start, end) { // 获得所有的表格行 this.rows = (function() { var tab = $(id); if(tab.tBodies.length == 0) { return tab.rows; } var rows = []; for(var i = 0; i < tab.tBodies.length; i++) { for(var j = 0; j < tab.tBodies[i].rows.length; j++) { rows.push(tab.tBodies[i].rows[j]); } } return rows; })(); this.start = start || Table.DEFAULT_START; this.end = end || Table.DEFAULT_END; this.time = time || Table.DEFAULT_TIME; // 生成渐变色实例 var color = new ColorGradient(this.start, this.end, 16); // 获得渐变色所有的颜色 this.grad = color.getGradient(); // 获得渐变的步长 this.step = color.getStep(); } // 默认的间隔时间 Table.DEFAULT_TIME = 10; // 默认的起始颜色 Table.DEFAULT_START = '#dcdcdc'; // 默认的结束颜色 Table.DEFAULT_END = '#ffffff'; Table.prototype = { // 为各表格行添加事件 addEvent : function() { for(var i = 0; i < this.rows.length; i++) { // 将所有的表格行的背景色设为结束色 this.rows[i].style.backgroundColor = this.end; // 使用 this.overEvent 事件处理程序为表格行添加 onmouseover 事件 Event.addEvent(this.rows[i], 'mouseover', Event.getFunction(this, this.overEvent, this.rows[i])); // 使用 this.outEvent 事件处理程序为表格行添加 onmouseout 事件 Event.addEvent(this.rows[i], 'mouseout', Event.getFunction(this, this.outEvent, this.rows[i])); } }, // 用于表格行 onmouseover 的事件处理 overEvent : function(row) { row.style.backgroundColor = this.start; row.change = this.step; }, // 用于表格行 onmouseout 的事件处理 outEvent : function(row) { // 由于 outEvent 在执行时不属于 Table 这个类中,必须找个变量进行代理引用 var me = this; if(row.change-- > 0) { // 逐渐更改背景色 row.style.backgroundColor = '#' + me.grad[me.step - row.change]; // 重复执行 outEvent setTimeout(function() { // 这里使用 me 的 Table 引用,由于 this 在这里所指的是 window 对象 me.outEvent(row); }, this.time); } }, // 调试用代码 _getRows : function(id) { var tab = $(id); alert(tab.tBodies.length); } }
这里好像不能上传附件,完整的代码可以到 http://download.csdn.net/source/721339 上下载,如果没有 CSDN 账号或者是无法下载,请联系 frankiegao123@gmail.com
没有评论:
发表评论