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 相关文章推荐
基于jquery的lazy loader插件实现图片的延迟加载[简单使用]
May 07 Javascript
用JS在浏览器中创建下载文件
Mar 05 Javascript
移动端js触摸事件详解
Sep 18 Javascript
Angularjs实现带查找筛选功能的select下拉框示例代码
Oct 04 Javascript
Javascript vue.js表格分页,ajax异步加载数据
Oct 24 Javascript
正则中的回溯定义与用法分析【JS与java实现】
Dec 27 Javascript
使用html+js+css 实现页面轮播图效果(实例讲解)
Sep 21 Javascript
JavaScrip关于创建常量的知识点
Dec 07 Javascript
js+html5实现手机九宫格密码解锁功能
Jul 30 Javascript
Vue退出登录时清空缓存的实现
Nov 12 Javascript
基于Cesium绘制抛物弧线
Nov 18 Javascript
Vue实现一种简单的无限循环滚动动画的示例
Jan 10 Vue.js
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
Protoss兵种介绍
2020/03/14 星际争霸
PHP 字符串正则替换函数preg_replace使用说明
2011/07/15 PHP
对google个性主页的拖拽效果的js的完整注释[转]
2007/04/10 Javascript
分享一个自己写的table表格排序js插件(高效简洁)
2011/10/29 Javascript
jquery实现带单选按钮的表格行选中时高亮显示
2013/08/01 Javascript
深入理解JavaScript是如何实现继承的
2013/12/12 Javascript
jQuery中(function($){})(jQuery)详解
2015/07/15 Javascript
JS+CSS实现闪烁字体效果代码
2016/04/05 Javascript
AngularJS中directive指令使用之事件绑定与指令交互用法示例
2016/11/22 Javascript
jsp 自动编译机制详细介绍
2016/12/01 Javascript
Bootstrap CSS布局之表单
2016/12/17 Javascript
JS实现点击表头表格自动排序(含数字、字符串、日期)
2017/01/22 Javascript
在点击div中的p时,如何阻止事件冒泡
2017/02/07 Javascript
js 作用域和变量详解
2017/02/16 Javascript
基于vue实现分页/翻页组件paginator示例
2017/03/09 Javascript
JavaScript去掉数组重复项的方法分析【测试可用】
2018/07/19 Javascript
vue服务端渲染缓存应用详解
2018/09/12 Javascript
JavaScript变速动画函数封装添加任意多个属性
2019/04/03 Javascript
[13:21]DOTA2国际邀请赛采访专栏:RSnake战队国士无双,Fnatic.Fly
2013/08/06 DOTA
[01:48]帕吉至宝加入游戏,遗迹战场现“千劫神屠”
2018/04/07 DOTA
python杀死一个线程的方法
2015/09/06 Python
Java Web开发过程中登陆模块的验证码的实现方式总结
2016/05/25 Python
简单谈谈Python中的几种常见的数据类型
2017/02/10 Python
基于Python_脚本CGI、特点、应用、开发环境(详解)
2017/05/23 Python
Python实现的读写json文件功能示例
2018/06/05 Python
解决python3 安装完Pycurl在import pycurl时报错的问题
2018/10/15 Python
使用matplotlib的pyplot模块绘图的实现示例
2020/07/12 Python
canvas实现滑动验证的实现示例
2020/08/11 HTML / CSS
物业保安主管岗位职责
2013/12/25 职场文书
怎样客观的做好自我评价
2013/12/28 职场文书
机械个人求职信范文
2014/01/24 职场文书
护士进修自我鉴定
2014/02/07 职场文书
生产操作工岗位职责
2014/09/16 职场文书
2015年度村委会工作总结
2015/04/29 职场文书
学生会宣传部竞选稿
2015/11/21 职场文书
laravel添加角色和模糊搜索功能的实现代码
2021/06/22 PHP