【头题】这又是一篇探讨文。即为我学习中总结,不是教程,不是技术样板,请你抱着怀疑的、挑错的态度来阅读此文。
JavaScript和DOM结合的如此之紧,几乎很大一部分代码都是在操作结点。其中就会涉及到设置修改节点的样式。
驼峰写法与浏览器兼容性
所谓“驼峰写法”即是指由有语意的单词组成的键值从第二个单词起要首字母大写,如背景颜色“background-color”使用JS就需要写成“backgroundColor”。类似的还有marginLeft、fontSize、backgroundPosition、overflowX等等。。。
但是也有一些容易犯的陷阱,如可不要把background写成backGround、overflow写成overFlow。。。。
还有浏览器的兼容性问题,有两点要注意,一个是透明opacity,IE下不直接支持透明,但支持滤镜透明,即要写成“alpha(opacity=value)”;另一个是浮动float(float是保留字),IE下是styleFloat,火狐、chrome等标准浏览器下是cssFloat。opera貌似是两者都支持。
最基本的写法
node.style.style-key=value
这种做法来说,没有什么不妥,缺点在大多数人看来也就是需要重复写太多代码。比如将node节点样式设置为“高度200像素,宽度300像素,右浮动,背景颜色为红色”,就需要写以下大堆的代码:
node.style.height="200px";
node.style.width="300px";
node.style.cssFloat="right";//标准浏览器
node.style.styleFloat="right";//IE
node.style.backgroundColor="red";
有人就会觉得前面一大堆“node.style.”重复性的代码完全可以通过函数封装来省略书写。其实还可以这样来写
var sty=node.style;
sty.height="200px";
sty.width="300px";
sty.cssFloat="right";//标准浏览器
sty.styleFloat="right";//IE
sty.backgroundColor="red";
这样就少了很多的代码。
不过通过函数封装可以将写法更加简单化。所以就有了下面的方法
函数封装后的方法
/*!
@FileOverview 设置节点样式
@Author liuqiqi || imqiqiboy@g mail.com || http://www.qiqiboy.com
@date 2010/11/29
@param node 节点对象
@param css 设置的样式,对象写法,同时兼容短横线相隔与驼峰写法,eg: {'height':'200px',width:'300px',margin-left:'20px',marginTop:'10px'}
@return none
*/
function setNodeStyle(node,css){
for(var _atr in css){ //枚举每个值
var arr = _atr.split('-'), //分割成数组
atr = _atr, //复制到一个变量方便以后引用原值
isie = !-[1,]; //判断是否是IE浏览器
for(var i = 1; i < arr.length; i++) //从分割后得到的数组的第二个元素开始,将第一个字符大写
arr[i] = arr[i].substring(0,1).toUpperCase() + arr[i].substring(1);
atr = arr.join('');//重新将数组连接成一个字串
switch(atr){
case 'opacity':
isie ? node.style.filter = 'alpha(opacity='+css[_atr]*100+')' : node.style[atr] = css[_atr];//针对不同浏览器下的设置
break;
case 'float':
isie ? node.style.styleFloat = css[_atr] : node.style.cssFloat=css[_atr];
break;
default:node.style[atr] = css[_atr];
break;
}
}
}
/* 例子 */
var node= document.getElementById("node");
setNodeStyle(node,{ 'height':'200px',
width:'300px',
margin-left:'20px',
marginTop:'10px',
'opacity':'0.8' }
其它方便的写法
其实有一个方法十分的方便,google的服务中很多都是使用这种写法,兼容性也十分好,从IE6到opera都支持良好。那就是cssText,如
node.style.cssText='height:200px;width:300px;background-color:red;'
就如同正常书写css代码一样,但是记住此处不要再使用驼峰写法了。
还有一个方法是使用setAttribute方法,如
node.setAttribute('style','height:200px;width:200px;background-color:red;')
这种写法也支持连写。
各种写法的优缺点
从代码量上看,“最基本的写法”所需的代码做多,函数封装后的代码次之,cssText和setAttribute写法所需代码量最少。
从性能上来看,由于函数封装和“最基本的写法”本质上是一样的,是一个一个样式设置的。我觉得每设置一个样式应该都会触发浏览器的一个现场更新,重绘页面。比如如果设置高度、宽度、背景色、透明度四个样式,那么就需要四次现场更新。所以此种写法应该是很不划算的。即是说已经有浏览器对这方面进行了优化,可以将短时间内的会引起现场更新的操作放到一个队列里,之后一起更新。但是保险起见,鉴于有更好的方法的话,尽量少用此种方法。
至于cssText和setAttribute这种连写方法,浏览器是如何处理的我不得而知,不过我觉得应该是将样式一次应用于节点,只需更新一次现场即可的。
所以我觉得还是使用cssText和setAttribute是比较好的(个人观点,欢迎反驳)。
更改节点样式的最佳模式
这里是讨论模式,而不是方法。我觉得基于尽量减少浏览器现场更新的思想,最好的做法的对节点设置类,然后在css中对这个类进行样式定义。比如还用上面的例子,将node节点样式设置为“高度200像素,宽度300像素,右浮动,背景颜色为红色”,我就可以用如下思路
//页面的.css文件中写入
.new{
height:200px;
width:300px;
float:right;
background-color:red;
}
//JavaScript代码
node.className += ' new';
这样通过一次现场更新就可以完成样式更新。要恢复默认样式就可以删除new这个类就行了。这种方法也可以降低css和JS的耦合度,如果你未来需要更新另一种样式,则只需修改css即可,JS不需要改动(JavaScript最佳实践思想)。
当然,对于需要较多次的样式修改,这种方法就有些繁琐了。至于如何选择,就需要我们在性能和简洁方面找到一个平衡点。
