使用JavaScript创建新样式表和新样式规则


Posted in PHP onJune 14, 2016

如今的这个年代,流行在Web页面上使用了大量的JavaScript,我们需要寻找各种方式来优化它们,使它们更快。我们使用事件委托来让事件监听器更有效率,使用降频技术来限定某些方法的使用次数,使用各种JavaScript加载器来动态加载我们需要的资源,等等。另外一种让页面更高效、更敏捷的方法是动态的添加或移除样式表里的样式,而不需要去查询DOM元素,对每个元素做样式调整。下面我们就来看看如何使用这种技术!

捕获样式表

你的页面上可能引用了不只一个的样式文件,你可以选择其中的一个。如果你指定了某个,你可以在HTML页面中的LINK 和 STYLE标签上加入ID来进行区别,获取CSSStyleSheet对象,它存放在document.styleSheets对象里。

var sheets = document.styleSheets; // 返回一个StyleSheetList数组

/*
返回: 

StyleSheetList {0: CSSStyleSheet, 1: CSSStyleSheet, 2: CSSStyleSheet, 3: CSSStyleSheet, 4: CSSStyleSheet, 5: CSSStyleSheet, 6: CSSStyleSheet, 7: CSSStyleSheet, 8: CSSStyleSheet, 9: CSSStyleSheet, 10: CSSStyleSheet, 11: CSSStyleSheet, 12: CSSStyleSheet, 13: CSSStyleSheet, 14: CSSStyleSheet, 15: CSSStyleSheet, length: 16, item: function}
*/

// 找到你想要修改的样式表
var sheet = document.styleSheets[0];

一个重要的需要注意的事情是样式表的media属性——如果你不小心,当想往屏幕显示使用的样式表里做修改操作时,你也许会错误的修改了用于打印(print)时使用的样式表。CSSStyleSheet对象里有各种属性信息,需要时你可以从中获取。

// Get info about the first stylesheet
console.log(document.styleSheets[0]);

/*
返回结果: 

CSSStyleSheet
 cssRules: CSSRuleList
 disabled: false
 href: "http://davidwalsh.name/somesheet.css"
 media: MediaList
 ownerNode: link
 ownerRule: null
 parentStyleSheet: null
 rules: CSSRuleList
 title: null
 type: "text/css"
*/

// Get the media type
console.log(document.styleSheets[0].media.mediaText)
/*
Returns:
 "all" or "print" or whichever media is used for this stylesheet
*/

有很多方法都可以让你捕获一个样式表,往里面添加新样式规则。

创建一个新的样式表

大多数时候,最好的方法是创建一个新的STYLE元素,动态的往里面添加规则。非常简单:

var sheet = (function() {
 // Create the <style> tag
 var style = document.createElement("style");

 // 如果你愿意的话,可以添加media属性 (或 media query) 
 // style.setAttribute("media", "screen")
 // style.setAttribute("media", "@media only screen and (max-width : 1024px)")

 // WebKit 补丁 
 style.appendChild(document.createTextNode(""));

 // Add the <style> element to the page
 document.head.appendChild(style);

 return style.sheet;
})();

不幸的是,WebKit类型的浏览器需求做一点点小修改,才能让上面的代码正确的运行,但不管怎样,我们获得了想要的sheet。

添加样式规则 ? 标准的addRule方法

CSSStyleSheet对象里有一个addRule方法,它可以接受3个参数:选择器、样式规则的CSS代码和一个整数,这个整数用来指示样式表的位置(相对于同样的选择器):

sheet.addRule("#myList li", "float: left; background: red !important;", 1);
位置缺省值为-1,表示放在最后。为了进行额外的控制,或偷懒的写法,你可以在规则里添加!important来消除位置引起的问题。调用addRule会返回-1——它什么都不表示。

你会发现,这种技术的优势在于,它可以动态的往页面上添加样式规则,并应用它们;你不必对每个元素进行操作,浏览器会自动应用这些规则。高效吧!

新增样式规则

CSSStyleSheet对象里还有一个insertRule方法,但在早期的IE里是没有这个方法的。insertRule方法把addRule方法的前两个参数混合到了一起:

sheet.insertRule("header { float: left; opacity: 0.8; }", 1);
这个方法看起来很丑陋,但无疑也是非常有用的。

安全的应用样式规则

因为并不是所有的浏览器都支持insertRule,最好我们做一些封装来确保代码的有效执行。下面就是一个很简单的封装方法:

function addCSSRule(sheet, selector, rules, index) {
 if(sheet.insertRule) {
 sheet.insertRule(selector + "{" + rules + "}", index);
 }
 else {
 sheet.addRule(selector, rules, index);
 }
}

// Use it!
addCSSRule(document.styleSheets[0], "header", "float: left");

这个方法可以应对各种情况。如果你想把这个方法里的代码单独拿出来使用,最好用try{}catch(e){}把它们包起来。

为媒体查询(Media Queries)增加样式规则

有两个方法可以为特定的媒体查询增加样式规则。第一种是通过标准的insertRule方法:

sheet.insertRule("@media only screen and (max-width : 1140px) { header { display: none; } }");
因为老式的IE不支持insertRule,我们可以使用另外一种方法,就是创建一个STYLE元素,赋予它正确的media属性,然后往里面添加新的样式规则。这种方式会增加额外的STYLE元素,但十分的简单。

我认为动态的往样式表里添加样式规则是一种十分高效而且简单的技术。记住在你的下一个应用里试一下这种技术,它会省了你很多功夫。

(英文:Add Rules to Stylesheets with JavaScript.)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
简体中文转换为繁体中文的PHP函数
Oct 09 PHP
php快速url重写 更新版[需php 5.30以上]
Apr 20 PHP
处理(php-cgi.exe - FastCGI 进程超过了配置的请求超时时限)的问题
Jul 03 PHP
php实现MD5加密16位(不要默认的32位)
Aug 12 PHP
php中的静态变量的基本用法
Mar 20 PHP
PHP获取mysql数据表的字段名称和详细信息的方法
Sep 27 PHP
php的sso单点登录实现方法
Jan 08 PHP
php判断输入是否是纯数字,英文,汉字的方法
Mar 05 PHP
php+curl 发送图片处理代码分享
Jul 09 PHP
PHP自带方法验证邮箱是否存在
Feb 01 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
Mar 31 PHP
PHP实现百度人脸识别
May 06 PHP
PHP list() 将数组中的值赋给变量的简单实例
Jun 13 #PHP
PHP处理二进制数据的实现方法
Jun 13 #PHP
PHP 在数组中搜索给定的简单实例 array_search 函数
Jun 13 #PHP
phpmailer简单发送邮件的方法(附phpmailer源码下载)
Jun 13 #PHP
PHP array_key_exists检查键名或索引是否存在于数组中的实现方法
Jun 13 #PHP
PHP简单获取多个checkbox值的方法
Jun 13 #PHP
浅谈PHP检查数组中是否存在某个值 in_array 函数
Jun 13 #PHP
You might like
单位速度在实战中的运用
2020/03/04 星际争霸
星际争霸 Starcraft 发展史
2020/03/14 星际争霸
ThinkPHP写第一个模块应用
2012/02/20 PHP
关于UEditor编辑器远程图片上传失败的解决办法
2012/08/31 PHP
PHP return语句另类用法不止是在函数中
2014/09/17 PHP
PHP四种排序算法实现及效率分析【冒泡排序,插入排序,选择排序和快速排序】
2018/04/27 PHP
Jquery 高亮显示文本中重要的关键字
2009/12/24 Javascript
JavaScript 学习笔记(十二) dom
2010/01/21 Javascript
jquery自定义下拉列表示例
2014/04/25 Javascript
JavaScript中的函数的两种定义方式和函数变量赋值
2014/05/12 Javascript
BootStrap文件上传样式超好看【持续更新】
2016/05/10 Javascript
js实现动态创建的元素绑定事件
2016/07/19 Javascript
AngularJs基于角色的前端访问控制的实现
2016/11/07 Javascript
浅析script标签中的defer与async属性
2016/11/30 Javascript
基于jQuery实现火焰灯效果导航菜单
2017/01/04 Javascript
AngularJS实现select的ng-options功能示例
2017/07/12 Javascript
vue中的非父子间的通讯问题简单的实例代码
2017/07/19 Javascript
react router4+redux实现路由权限控制的方法
2018/05/03 Javascript
从0到1搭建element后台框架优化篇(打包优化)
2019/05/12 Javascript
[55:25]2018DOTA2亚洲邀请赛3月29日 小组赛A组 VG VS OG
2018/03/30 DOTA
python连接mongodb操作数据示例(mongodb数据库配置类)
2013/12/31 Python
基于python进行桶排序与基数排序的总结
2018/05/29 Python
对Tensorflow中的矩阵运算函数详解
2018/07/27 Python
python绘制评估优化算法性能的测试函数
2019/06/25 Python
python求最大值最小值方法总结
2019/06/25 Python
详解Python3 中的字符串格式化语法
2020/01/15 Python
JD Sports法国:英国篮球和运动时尚的领导者
2017/09/28 全球购物
毕业生欢送会主持词
2014/03/31 职场文书
《青海高原一株柳》教学反思
2014/04/25 职场文书
员工薪酬激励方案
2014/06/13 职场文书
职工小家建设活动方案
2014/08/25 职场文书
2015关爱留守儿童工作总结
2014/12/12 职场文书
怎样写离婚协议书
2015/01/26 职场文书
大学生团员个人总结
2015/02/14 职场文书
2015年化工厂工作总结
2015/05/04 职场文书
生日寿星公答谢词
2015/09/29 职场文书