JS函数实现动态添加CSS样式表文件


Posted in Javascript onDecember 15, 2012

先给出函数。

varaddSheet=function(){ 
vardoc,cssCode; 
if(arguments.length==1){ 
doc=document; 
cssCode=arguments[0] 
}elseif(arguments.length==2){ 
doc=arguments[0]; 
cssCode=arguments[1]; 
}else{ 
alert("addSheet函数最多接受两个参数!"); 
} 
if(!+"v1"){//增加自动转换透明度功能,用户只需输入W3C的透明样式,它会自动转换成IE的透明滤镜 
vart=cssCode.match(/opacity:(d?.d+);/); 
if(t!=null){ 
cssCode=cssCode.replace(t[0],"filter:alpha(opacity="+parseFloat(t[1])*100+")") 
} 
} 
cssCode=cssCode+" ";//增加末尾的换行符,方便在firebug下的查看。 
varheadElement=doc.getElementsByTagName("head")[0]; 
varstyleElements=headElement.getElementsByTagName("style"); 
if(styleElements.length==0){//如果不存在style元素则创建 
if(doc.createStyleSheet){//ie 
doc.createStyleSheet(); 
}else{ 
vartempStyleElement=doc.createElement('style');//w3c 
tempStyleElement.setAttribute("type","text/css"); 
headElement.appendChild(tempStyleElement); 
} 
} 
varstyleElement=styleElements[0]; 
varmedia=styleElement.getAttribute("media"); 
if(media!=null&&!/screen/.test(media.toLowerCase())){ 
styleElement.setAttribute("media","screen"); 
} 
if(styleElement.styleSheet){//ie 
styleElement.styleSheet.cssText+=cssCode; 
}elseif(doc.getBoxObjectFor){ 
styleElement.innerHTML+=cssCode;//火狐支持直接innerHTML添加样式表字串 
}else{ 
styleElement.appendChild(doc.createTextNode(cssCode)) 
} 
}

有时我们需要在.js文件对文档动态引入一些CSS样式。对于一些短小的CSS代码来说,这好办,我们可以调用其style方法,如

varddd=document.getElementById("ddd"); 
ddd.style.border="1pxsolidred";

如果再长一点也无所谓:

varddd=document.getElementById("ddd"); 
ddd.style.cssText="border:1pxsolidred;color:#000;background:#444;float:left";

本人而言,我是喜欢后者。因为前者有严重的兼容问题。如float这个样式,在IE是styleFloat,在火狐等W3C标准游览器是cssFloat。而cssText则是通吃。

如果很长,我们可以动态导入一CSS文件。如

functionaddSheetFile(path){ 
varfileref=document.createElement("link") 
fileref.rel="stylesheet"; 
fileref.type="text/css"; 
fileref.href=path; 
fileref.media="screen"; 
varheadobj=document.getElementsByTagName('head')[0]; 
headobj.appendChild(fileref); 
}

这个函数在IE中有点累赘。我向来是支持哪个游览器就用哪个游览器的原生函数,直接使用二进制代码效率最高。

varoStylesheet=document.createStyleSheet(sURL,iIndex);

createStyleSheet带的两个参数都是可选的。

但如果我们的样式是某个页面独有的,而且只有管理员才能使用到,而且那部分页面是动态生成的,我们需要一开始就引入它吗?需要特意弄个文件来装载它吗?最好的方法让这些样式与动态脚本捆绑在一起。我这个函数就为此而开发的。

坦白说,它最开始是为富文本编辑器而开发的。大家都知道,富文本输入框最流行的做法是把要输入的内容放到iframe中,这就涉及到两种document,一个主页面的document,另一个是iframe的document。iframe的document又涉及到兼容问题。我们可以:
variframe=document.createElement('iframe');//生成用于编辑的richtexteditor
variframeDocument=iframe.contentDocument||iframe.contentWindow.document;
……

嘛,扯远了。总而言之,函数最开始的判定就是为这两种document而准备。如果没有涉及到iframe,我们只传入一个参数就行了。最后一个参数永远是CSS字符串。

然后是动态生成styleSheet元素,把CSS字符串加入到此元素的问题。当然如果有现阶段的,当然就用现成的。DOM元素越多对游览器的负担就越大。我们想到document.styleSheets方法。它返回一个集合,包含style元素与link元素,还涉及一兼容问题,如:

<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<htmlxmlns=" 
<head> 
<metahttp-equiv="content-type"content="text/html;charset=UTF-8"/> 
<%#强制IE8像IE7一样呈现网页-%> 
<metahttp-equiv=”X-UA-Compatible”content=”IE=EmulateIE7″/> 
<%#--默认所有的链接都在本窗口打开-%> 
<basetarget="_self"/> 
<title><%=h(yield(:title))||controller.action_name%></title> 
<%=stylesheet_link_tag"screen","button","style"%> 
<linkrel="stylesheet"href="/stylesheets/print.css"type="text/css"media="print"> 
<!--[ifltIE8]> 
<linkrel="stylesheet"href="/stylesheets/ie.css"type="text/css"media="screen"> 
<![endif]--> 
<%=javascript_tag"window._token='#{form_authenticity_token}'"ifActionController::Base.allow_forgery_protection%> 
<%=javascript_include_tag:defaults%> 
<styletype="text/css"media="print"></style> 
</head>

上面用alert(document.styleSheets.length);测试一下,IE返回6,W3C游览器返回5。因此,否决了它。而且我们只用到style元素,不使用外联。第二部分的判定就针对head中的style元素而言,没有就创建一个。然后我们把CSS字符串加在第一个style元素就行了。

接着我们要加把保险锁,因为当media="print"时,只在页面打印时,定义的效果才有效。为了防止第一个style元素的media值不是screen,我们得改一改。

varstyleElement=styleElements[0]; 
varmedia=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.tabletd{font-size:12px;color:red;text-align:center;} 
");*/ 
对比一下51js的客服果果脚本,更短小,但是它会可能会创建多个style元素,还有一些效率的问题……毕竟我这个最初是为开发富文本编辑而开发的,功能不强大不行啊! 
/* 
动态添加样式表的规则 
*/ 
iCSS={add:function(css){ 
varD=document,$=D.createElement('style'); 
$.setAttribute("type","text/css"); 
$.styleSheet&&($.styleSheet.cssText=css)|| 
$.appendChild(D.createTextNode(css)); 
D.getElementsByTagName('head')[0].appendChild($); 
}}; 
iCSS.add(" 
.dhoooListBox,.dhoooListBoxli{margin:0;padding:0;list-style-type:none;font-size:12px;cursor:default} 
.dhoooListBox{border:1pxsolid#aaa;width:180px;background:#eee;height:200px;overflow:auto;float:left} 
.dhoooListBoxli{margin:5px;line-height:24px;background:url(images/smilies/time.gif)no-repeat060%;padding-left:25px;color:#555;} 
.dhoooListBoxli.selected{background-color:#FFCC33} 
"); 

最后追加几个相关的方法: 
vargetClass=function(ele){ 
returnele.className.replace(/s+/,'').split(''); 
}; 
varhasClass=function(ele,cls){ 
returnele.className.match(newRegExp('(\s|^)'+cls+'(\s|$)')); 
} 
varaddClass=function(ele,cls){ 
if(!this.hasClass(ele,cls))ele.className+=""+cls; 
} 
varremoveClass=function(ele,cls){ 
if(hasClass(ele,cls)){ 
varreg=newRegExp('(\s|^)'+cls+'(\s|$)'); 
ele.className=ele.className.replace(reg,''); 
} 
}
Javascript 相关文章推荐
奉献给JavaScript初学者的编写开发的七个细节
Jan 11 Javascript
jquery和javascript中如何将一元素的内容赋给另一元素
Jan 09 Javascript
微信小程序(应用号)开发新闻客户端实例
Oct 24 Javascript
js实现图片切换(动画版)
Dec 25 Javascript
jquery.cookie.js的介绍与使用方法
Feb 09 Javascript
DOM事件探秘篇
Feb 15 Javascript
JavaScript简单拖拽效果(1)
May 17 Javascript
vue页面跳转后返回原页面初始位置方法
Feb 11 Javascript
AngularJS中的作用域实例分析
May 16 Javascript
layer.confirm取消按钮绑定事件的方法
Aug 17 Javascript
vue+vuex+json-seiver实现数据展示+分页功能
Apr 11 Javascript
如何在node环境实现“get数据解析”代码实例
Jul 03 Javascript
js修改地址栏URL参数解决url参数问题
Dec 15 #Javascript
jquery插件如何使用 jQuery操作Cookie插件使用介绍
Dec 15 #Javascript
JavaScript中OnLoad几种使用方法
Dec 15 #Javascript
Javascript中自动切换焦点实现代码
Dec 15 #Javascript
treepanel动态加载数据实现代码
Dec 15 #Javascript
FF火狐下获取一个元素同类型的相邻元素实现代码
Dec 15 #Javascript
javascript错误的认识不用关心内存管理
Dec 15 #Javascript
You might like
php 字符串函数收集
2010/03/29 PHP
php实现将Session写入数据库
2015/07/26 PHP
CI框架实现优化文件上传及多文件上传的方法
2017/01/04 PHP
基于PHP的加载类操作以及其他两种魔术方法的应用实例
2017/08/28 PHP
Laravel 使用查询构造器配合原生sql语句查询的例子
2019/10/12 PHP
js弹出窗口之弹出层的小例子
2013/06/17 Javascript
JavaScript中的方法重载实例
2015/03/16 Javascript
ajax读取数据后使用jqchart显示图表的方法
2015/06/10 Javascript
jquery+css实现的红色线条横向二级菜单效果
2015/08/22 Javascript
谈一谈jQuery核心架构设计
2016/03/28 Javascript
浅析jquery与checkbox的checked属性的问题
2016/04/27 Javascript
探索Javascript中this的奥秘
2016/12/11 Javascript
AngularJs篇:使用AngularJs打造一个简易权限系统的实现代码
2016/12/26 Javascript
jQuery实现获取h1-h6标题元素值的方法
2017/03/06 Javascript
JS操作xml对象转换为Json对象示例
2017/03/25 Javascript
详解vue项目构建与实战
2017/06/27 Javascript
Angular 2.0+ 的数据绑定的实现示例
2017/08/09 Javascript
JavaScript 中使用 Generator的方法
2017/12/29 Javascript
使用Vue实现图片上传的三种方式
2018/07/17 Javascript
vue 列表页跳转详情页获取id以及详情页通过id获取数据
2019/03/27 Javascript
Vue程序化的事件监听器(实例方案详解)
2020/01/07 Javascript
JavaScript设计模式--简单工厂模式实例分析【XHR工厂案例】
2020/05/23 Javascript
[01:03:56]Mineski vs TNC 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
[48:46]完美世界DOTA2联赛PWL S2 SZ vs FTD.C 第二场 11.19
2020/11/19 DOTA
Python3写入文件常用方法实例分析
2015/05/22 Python
Python实现图片识别加翻译功能
2019/12/26 Python
英国第一的市场和亚马逊替代品:OnBuy
2019/03/16 全球购物
英国名牌男装店:Standout
2021/02/17 全球购物
土木工程应届生求职信
2013/10/31 职场文书
国际政治个人自荐信范文
2013/11/26 职场文书
《绿色蝈蝈》教学反思
2014/03/02 职场文书
节水口号标语
2014/06/19 职场文书
2016大学生形势与政策心得体会
2016/01/12 职场文书
MySQL 可扩展设计的基本原则
2021/05/14 MySQL
mysql 子查询的使用
2022/04/28 MySQL
设置IIS Express并发数
2022/07/07 Servers