http://www.cnblogs.com/rubylouvre/archive/2009/07/14/1523104.html
先给出函数。
01.
var
addSheet =
function
(){
02.
var
doc,cssCode;
03.
if
(arguments.length == 1){
04.
doc = document;
05.
cssCode = arguments[0]
06.
}
else
if
(arguments.length == 2){
07.
doc = arguments[0];
08.
cssCode = arguments[1];
09.
}
else
{
10.
alert(
"addSheet函数最多接受两个参数!"
);
11.
}
12.
if
(!+
"/v1"
){
//增加自动转换透明度功能,用户只需输入W3C的透明样式,它会自动转换成IE的透明滤镜
13.
var
t = cssCode.match(/opacity:(/d?/./d+);/);
14.
if
(t!=
null
){
15.
cssCode = cssCode.replace(t[0],
"filter:alpha(opacity="
+ parseFloat(t[1]) * 100+
")"
)
16.
}
17.
}
18.
cssCode = cssCode +
"/n"
;
//增加末尾的换行符,方便在firebug下的查看。
19.
var
headElement = doc.getElementsByTagName(
"head"
)[0];
20.
var
styleElements = headElement.getElementsByTagName(
"style"
);
21.
if
(styleElements.length == 0){
//如果不存在style元素则创建
22.
if
(doc.createStyleSheet){
//ie
23.
doc.createStyleSheet();
24.
}
else
{
25.
var
tempStyleElement = doc.createElement(
'style'
);
//w3c
26.
tempStyleElement.setAttribute(
"type"
,
"text/css"
);
27.
headElement.appendChild(tempStyleElement);
28.
}
29.
}
30.
var
styleElement = styleElements[0];
31.
var
media = styleElement.getAttribute(
"media"
);
32.
if
(media !=
null
&& !/screen/.test(media.toLowerCase()) ){
33.
styleElement.setAttribute(
"media"
,
"screen"
);
34.
}
35.
if
(styleElement.styleSheet){
//ie
36.
styleElement.styleSheet.cssText += cssCode;
37.
}
else
if
(doc.getBoxObjectFor){
38.
styleElement.innerHTML += cssCode;
//火狐支持直接innerHTML添加样式表字串
39.
}
else
{
40.
styleElement.appendChild(doc.createTextNode(cssCode))
41.
}
42.
}
有时我们需要在.js文件对文档动态引入一些CSS样式。对于一些短小的CSS代码来说,这好办,我们可以调用其style方法,如
1.
var
ddd = document.getElementById(
"ddd"
);
2.
ddd.style.border =
"1px solid red"
;
如果再长一点也无所谓:
1.
var
ddd = document.getElementById(
"ddd"
);
2.
ddd.style.cssText =
"border:1px solid red;color:#000;background:#444;float:left"
;
本人而言,我是喜欢后者。因为前者有严重的兼容问题。如float这个样式,在IE是styleFloat,在火狐等W3C标准游览器是cssFloat。而cssText则是通吃。
如果很长,我们可以动态导入一CSS文件。如
01.
function
addSheetFile(path){
02.
var
fileref=document.createElement(
"link"
)
03.
fileref.rel =
"stylesheet"
;
04.
fileref.type =
"text/css"
;
05.
fileref.href = path;
06.
fileref.media=
"screen"
;
07.
var
headobj = document.getElementsByTagName(
'head'
)[0];
08.
headobj.appendChild(fileref);
09.
}
这个函数在IE中有点累赘。我向来是支持哪个游览器就用哪个游览器的原生函数,直接使用二进制代码效率最高。
1.
var
oStylesheet = document.createStyleSheet ( sURL , iIndex );
createStyleSheet带的两个参数都是可选的。
但如果我们的样式是某个页面独有的,而且只有管理员才能使用到,而且那部分页面是动态生成的,我们需要一开始就引入它吗?需要特意弄个文件来装载它吗?最好的方法让这些样式与动态脚本捆绑在一起。我这个函数就为此而开发的。
坦白说,它最开始是为富文本编辑器而开发的。大家都知道,富文本输入框最流行的做法是把要输入的内容放到iframe中,这就涉及到两种document,一个主页面的document,另一个是iframe的document。 iframe的document又涉及到兼容问题。我们可以:
1.
var
iframe = document.createElement(
'iframe'
);
//生成用于编辑的rich text editor
2.
var
iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
3.
……
嘛,扯远了。总而言之,函数最开始的判定就是为这两种document而准备。如果没有涉及到iframe,我们只传入一个参数就行了。最后一个参数永远是CSS字符串。
然后是动态生成styleSheet元素,把CSS字符串加入到此元素的问题。当然如果有现阶段的,当然就用现成的。DOM元素越多对游览器的负担就越大。我们想到document.styleSheets方法。它返回一个集合,包含style元素与link元素,还涉及一兼容问题,如:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<%# 强制IE8像IE7一样呈现网页 -%>
<meta http-equiv=”X-UA-Compatible” content=”IE=EmulateIE7″ />
<%#--默认所有的链接都在本窗口打开 -%>
<base target="_self" />
<title><%= h(yield(:title)) || controller.action_name %></title>
<%= stylesheet_link_tag "screen","button","style" %>
<link rel="stylesheet" href="/stylesheets/print.css" type="text/css" media="print">
<!--[if lt IE 8]>
<link rel="stylesheet" href="/stylesheets/ie.css" type="text/css" media="screen">
<![endif]-->
<%= javascript_tag "window._token = '#{form_authenticity_token}'" if ActionController::Base.allow_forgery_protection %>
<%= javascript_include_tag :defaults %>
<style type="text/css" media="print"></style>
</head>
上面用alert(document.styleSheets.length);测试一下,IE返回6,W3C游览器返回5。因此,否决了它。而且我们只用到style元素,不使用外联。第二部分的判定就针对head中的style元素而言,没有就创建一个。然后我们把CSS字符串加在第一个style元素就行了。
接着我们要加把保险锁,因为当media="print"时,只在页面打印时,定义的效果才有效。为了防止第一个style元素的media值不是screen,我们得改一改。
var styleElement = styleElements[0];
var media = styleElement.getAttribute("media");
if(media != null && !/screen/.test(media.toLowerCase()) ){
styleElement.setAttribute("media", "screen");
}
附上media的一些说明。
- screen (缺省值),提交到计算机屏幕;
- print, 输出到打印机;
- projection,提交到投影机;
- aural,扬声器;
- braille,提交到凸字触觉感知设备;
- tty,电传打字机 (使用固定的字体);
- tv,电视机;
- all,所有输出设备。
最后是如此添加的问题。分IE,火狐与其他游览器三种。判定游览器也用各自的私有属性或方法。如styleSheet是IE独用的,getBoxObjectFor是火狐独用的(当然你也可以使用(/firefox/.test(navigator.userAgent.toLowerCase())),通常DOM操作是最耗时的,能用私有就用私有!
使用方法。
addSheet("/
.RTE_iframe{width:600px;height:300px;}/
.RTE_toolbar{width:600px;}/
.color_result{width:216px;}/
.color_view{width:110px;height:25px;}/
.color_code{text-align:center;font-weight:700;color:blue;font-size:16px;}/
div.table{width:176px;position:absolute;padding:1px;}/
div.table td{font-size:12px;color:red;text-align:center;}/
" );*/
最后追加几个相关的方法:
var getClass = function(ele) {
return ele.className.replace(//s+/,' ').split(' ');
};
var hasClass = function(ele,cls) {
return ele.className.match(new RegExp('(//s|^)'+cls+'(//s|$)'));
}
//更快的版本
var hasClass =function(ele,cls){
return -1 < (" "+ele.className+" ").indexOf(" "+cls+" ");
}
var addClass = function(ele,cls) {
if (!this.hasClass(ele,cls)) ele.className += " "+cls;
}
var removeClass = function(ele,cls) {
if (hasClass(ele,cls)) {
var reg = new RegExp('(//s|^)'+cls+'(//s|$)');
ele.className=ele.className.replace(reg,' ');
}
}