以前我就是一篇博文 就给出一个好用的函数,它在我几篇博文中被广泛运用的。最近看了不少东西,于是便有了这篇博文,以梳理我学到的新东西。
毫无疑问,基于表现与结构相分离的原则,直接导入一个新的样式表是最好的选择,但有些情况就行不通,如我们做一个能拖动的div,从设置样式的角度看,就是把它绝对定位,以防影响原来的文档流,然后一点点改变其top与left的值实现移动的效果。由于拖动是有时间概念的,一秒24帧,样式表不可能面面俱到都把它们写进去。因此动态生成样式规则与快速修改样式规则是非常有必要的,w3c为此做了大量的工作,在dom2.0中,扩充了不少接口。
退一步说,表现与结构相分离也不止导入样式表这一条路。要知道,一共有三种样式类型,外部样式,内部样式,与内联样式。
新添加的接口主要集中在外部样式中——之所以说接口,因为相应的实现是由浏览器方提供的,像ie6那样傲慢的家伙,从来无视它们的存在。
在w3c的模型中,type为"text/css"的link标签与style标签都是代表一个cssstylesheet对象,我们可以通过document.stylesheets 获得当前页面中所有的cssstylesheet对象,不过这是一个集合,非单纯的数组。每一个cssstylesheet对象拥有如下属性,
样式规则对象(cssstylerule object),是w3c为了对样式进行更细致的设定而搞出来的,如下面这个东西就是对应一个样式规则对象:
button[type] {
padding:4px 10px 4px 7px;
line-height:17px;
}
样式规则对象拥有如下几个主要属性:type,csstext,parentstylesheet,parentrule。
type有点类似节点的nodetype,对样式规则进行细分,它是用一个整数来表示其类型。具体情况如下
csstext不用多说,一个非常有用的属性,直接把字符串转换成样式规则,无视各浏览器样式属性的差异,如cssfloat 和stylefloat。
parentstylesheet和parentrule都是针对@import来说的。不过,@import在ie下有问题,我基本不用它。
|||
还有几个生不逢时的方法:
我们可以弄一个设定样式的函数出来:
var hyphenize =function(name){
return name.replace( /([a-z])/g, "-$1" ).tolowercase();
}
var capitalize = function(prop){
return prop.replace(//b[a-z]/g, function(match){
return match.touppercase();
});
}
var setstyle = function(el, styles) {
for (var property in styles) {
if(!styles.hasownproperty(property)) continue;
if(el.style.setproperty) {
//必须是连字符风格,el.style.setproperty('background-color','red',null);
el.style.setproperty(hyphenize(property),styles[property],null);
} else {
//必须是驼峰风格,如el.style.paddingleft = "2em"
el.style[camelize(property)] = styles[property]
}
}
return true;
}
使用方法:
setstyle(div,{
'left':0,
'top':0,
'line-height':'2em',
'padding-right':'4px'
});
不过我非常不喜欢这方法,生成的是内联样式,它还得特殊处理float与opacity。在ie7的内联样式中,滤镜还有一个bug,一定要让其得到haslayout,要不滤镜就不会生效(我们可以通过el.currentstyle.haslayout查看其状况)。因此,如其一个个设置,不如用csstext一网打尽。
最后附上我的加强版addsheet方法。它增添自动处理opacity的功能,也就是说我们只需要按标准设置csstext,它会自动生成相应的滤镜,这样一来至少让火狐等浏览器通过w3c的校检。
var addsheet = function(){
var doc,csscode;
if(arguments.length == 1){
doc = document;
csscode = arguments[0]
}else if(arguments.length == 2){
doc = arguments[0];
csscode = arguments[1];
}else{
alert("addsheet函数最多接受两个参数!");
}
if(!+"/v1"){//新增功能,用户只需输入w3c的透明样式,它会自动转换成ie的透明滤镜
var t = csscode.match(/opacity:(/d?/./d+);/);
if(t!= null){
csscode = csscode.replace(t[0], "filter:alpha(opacity="+ parsefloat(t[1]) * 100+");");
}
}
csscode = csscode + "/n";//增加末尾的换行符,方便在firebug下的查看。
var headelement = doc.getelementsbytagname("head")[0];
var styleelements = headelement.getelementsbytagname("style");
if(styleelements.length == 0){//如果不存在style元素则创建
if(doc.createstylesheet){ //ie
doc.createstylesheet();
}else{
var tempstyleelement = doc.createelement('style');//w3c
tempstyleelement.setattribute("type", "text/css");
headelement.appendchild(tempstyleelement);
}
}
var styleelement = styleelements[0];
var media = styleelement.getattribute("media");
if(media != null && !/screen/.test(media.tolowercase()) ){
styleelement.setattribute("media","screen");
}
if(styleelement.stylesheet){ //ie
styleelement.stylesheet.csstext += csscode;//添加新的内部样式
}else if(doc.getboxobjectfor){
styleelement.innerhtml += csscode;//火狐支持直接innerhtml添加样式表字串
}else{
styleelement.appendchild(doc.createtextnode(csscode))
}
}
原文:http://www.cnblogs.com/rubylouvre/archive/2009/08/30/1556869.html
新闻热点
疑难解答