在之前的文章中,我们使用DOM方法进行了添加,修改,样式设置,更新属性…,但是我们不得不思考一个问题:JavaScript作为处理行为层的语言实现交互,然而我们却用来处理表示层的信息,那么JavaScript岂不是和CSS性质无异?我们想要更换某些元素的样式,就只能去设置函数更改与样式设置有关的语句。这不是最好的方法,也不是JavaScript的意义所在,更高明的方法是:与其使用DOM直接改变某个元素的样式,不如通过JavaScript代码去更新这个元素的class属性 尤其在庞大的样式设置规模下,用class属性能够大大降低工作量下。面我们将用一个例子说明问题
通过JavaScript更新元素的class属性
在这篇文章何时选用CSS何时选用DOM?中我们设置了一个响应鼠标的事件处理函数,当鼠标悬浮时更新样式,字体加粗,背景颜色更换:
HTML标记
<table>
<tr>
<th>属性</th>
<th>描述</th>
<th>用法</th>
</tr>
<tr>
<td>width</td>
<td>表格的宽度</td>
<td>with:500px;</td>
</tr>
<tr>
<td>height</td>
<td>表格的高度</td>
<td>height:200px;</td>
</tr>
<tr>
<td>border</td>
<td>边框属性</td>
<td>border:1px soild #eee表示三个分量分别是粗细,实线填充,灰色</td>
</tr>
<tr>
<td>border-collapse</td>
<td>表格边框的坍缩</td>
<td>border-collapse:collapse;表示内部的单元格边框与表格边框重叠在一起</td>
</tr>
<tr>
<td>:nth-child(odd|even)</td>
<td>奇偶选择器,可以设置行或列</td>
<td>tr:nth-child(odd);</td>
</tr>
</table>
CSS样式:
table,th{
border: 1px solid #8A2BE2;
background-color: #B0C4DE;
border-collapse: collapse;
}
td:hover{
background-color: #fff;
}
tr:hover{
font-weight: bold;
background-color: #fff;
}
JavaScript函数:
function hightRows()
{
if(!document.getElementsByTagName) return false;
var rows=document.getElementsByTagName("tr");
for(var i=0;i<rows.length;i++)
{
rows[i].onmouseover=function()
{
this.style.fontWeight="bold";
this.style.backgroundColor="#fff";
}
rows[i].onmouseout=function()
{
this.style.fontWeight="normal";
this.style.backgroundColor="#B0C4DE";
}
}
}
更高明的方法是:与其使用DOM直接改变某个元素的样式,不如通过JavaScript代码去更新这个元素的class属性,尤其是在庞大的样式设置面前。我们要做的就是替换class属性,常用的方法是利用className属性或者setAttribute().
className属性可读可写,实用性非常强大。我们根据这个理念来设计:
(1)先设置两个class属性:
.style1{
font-weight:bold;
background-color:#fff;
}
.style2{
font-weight:normal;
background-color:#B0C4DE;
}
(2)然后在JavaScript中更新这两个class:
function JsHightRows()
{
if(!document.getElementsByTagName) return false;
var rows=document.getElementsByTagName("tr");
for(var i=0;i<rows.length;i++)
{
rows[i].onmouseover=function()
{
this.className="style1";
}
rows[i].onmouseout=function()
{
this.className="style2";
}
}
}
(3)由于this.className="style1"会直接更新className属性,如果只想要添加而非更新可以设置这样一个函数:
function addClass(elem,value)
{
if(!elem.className)
{
elem.className=value;
}
else
{
elem.className+=" "+value;
}
}
可以看到这种方法相比起大量的获取元素设置节点要方便的多。这也体现了JavaScript真正的用途:处理行为层而非表示层。设置方法也十分简单,将样式集中成一个类,替换这个类(className或.setAttribute(“class”,“style1”))就能达到目的。
对函数进行抽象
把一个具体的东西转换成通用的东西,这个过程叫做抽象。函数的设置意义在于函数是可以抽象的,可以适用范围会很广,可以被重用,模块化的设计会使得你的代码更加简洁。不同于c++,JavaScript中的函数不能设置成virtual,但是函数的参数类型是抽象的,这种通过抽象参数的抽象函数意义也十分重大,我们可以抽象参数从而抽象化我们的函数。
举一例子:
function JsHightRows()
{
if(!document.getElementsByTagName) return false;
var rows=document.getElementsByTagName("tr");
for(var i=0;i<rows.length;i++)
{
rows[i].onmouseover=function()
{
this.className="style1";
}
rows[i].onmouseout=function()
{
this.className="style2";
}
}
这个函数我们可以仅仅适用于tr标签,我们可以增加一个参数,将tr标签抽象,从而抽象化我们的函数:
function JsHightRows(tag)
{
if(!document.getElementsByTagName) return false;
var rows=document.getElementsByTagName(tag);
for(var i=0;i<rows.length;i++)
{
rows[i].onmouseover=function()
{
this.className="style1";
}
rows[i].onmouseout=function()
{
this.className="style2";
}
}
这样一来JsHightRows(tag)函数的适用范围不在仅仅是tr元素,而是所有元素。