[javascript][翻译]使用javascript添加css rule
来杭一周,收获很多,成长很多。
周六在搞一个插件的时候碰到需要动态添加伪元素的需求,搜了一下解决方案,有人用正则写出了读取伪元素的函数;我觉得倒是可以通过注入css rule的方式,来让预留有某些类的标签动态产生伪元素。
然后在google上搜到这样一篇文章,讲了一下之前没了解到的api函数:addrule等,翻译一下,分享一下好了。
原博文网址:http://davidwalsh.name/add-rules-stylesheets
译文如下:
因为我们在开发中javascript使用的越来越多,所以我们总是想尽办法想让它更快。我们使用事件代理来监听事件,使用函数节流来限制单位时间内函数的调用次数,使用loader方法来加载最需要的资源。这些方法都可以让我们的页面加载、渲染、执行的速度有一定的加快。本文要说另一种方法:通过动态添加删除CSS样式代替原有的查找节点并修改来应用某些样式。
- 获取样式表
我们可以选择向页面内的某条stylesheet中添加样式。可以给<link>标签或者<style>标签添加ID,通过引用节点的sheet属性来获取CSSStyleSheet对象。页面中的stylesheets可以使用document.styleSheets来获取:
var sheets = document.styleSheets;
// returns an Array-like StyleSheetList
//返回一个类数组对象 /*
Returns: 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}
*/ // Grab the first sheet, regardless of media
//先不管第一个样式的具体应用media(注:可能是print等)
var sheet = document.styleSheets[];
在我们选取link或者style标签时,我们应该考虑被选中的样式表标签是否是应用于screen,而不是print等。CSSStyleSheet对象给我们提供了这样的属性:
// Get info about the first stylesheet
console.log(document.styleSheets[0]); /*
Returns: 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
//获取media类型
console.log(document.styleSheets[0].media.mediaText)
/*
Returns:
"all" or "print" or whichever media is used for this stylesheet
*/
当然除了上面的,还有别的方法可以获取stylesheet对象。
- 创建新样式表
有些情况下,可能新建一个style节点来承装新添加的style rule。方法很简单:
var sheet = (function() {
// Create the <style> tag
var style = document.createElement("style");
// Add a media (and/or media query) here if you'd like!
// style.setAttribute("media", "screen")
// style.setAttribute("media", "only screen and (max-width : 1024px)")
// WebKit hack :(
//webkit内核浏览器的hack:
style.appendChild(document.createTextNode(""));
// Add the <style> element to the page 插入页面
document.head.appendChild(style);
return style.sheet;
})();
请留意上面第三条语句是为webkit浏览器添加的hack。
- 插入规则 insertRule(styles,[index])
Stylesheets对象提供了insertRule(译者注:IE8及以下不兼容,具体参考链接http://www.quirksmode.org/dom/w3c_css.html )方法。insertRule函数要求传入css样式风格的str作为参数。
具体调用方法:
sheet.insertRule("header { float: left; opacity: 0.8; }", 1);
(译者注:传入的样式str的格式要求很多。就我目前发现的:1.{}两个花括号和前后最好都有一个空格 2.如果是webkit内核,函数在解析带有-moz-前缀的样式规则时会抛err)
这种方法看上去有点丑,但是确实有用。第二个参数Index,表示我们将在样式内部的哪一条插入新样式css rule,这就可以帮助我们实现原有样式的覆盖。默认index取值是-1(译者注:但是输入-1在chrome 41下抛了err,提示参数不能小于0,这里值得在研究一下),表示默认在样式最后追加。如果想强制覆盖,可以使用!important,来避免插入次序引起其他问题。
- 添加规则(非标准函数) addRule(selector,styles,index)
CSSStyleSheet对象有一个非标准函数addRule,和insertRule相比,它更像js api的调用风格,无需自己注意插入的样式字符串的格式。addRule方法接受三个参数,分别是选择器selector,样式字符串"color:red;font-size:12px",和插入次序index。
sheet.addRule("#myList li", "float: left; background: red !important;", 1);
方法有返回值,为-1。但是没有什么具体含义。
这种方式可以快速高效的改变页面上节点的已有样式。
- 应用样式
因为上面提到两个函数都不是常见api函数,所以需要做浏览器兼容性处理。
function addCSSRule(sheet, selector, rules, index) {
if("insertRule" in sheet) {
sheet.insertRule(selector + "{" + rules + "}", index);
}
else if("addRule" in sheet) {
sheet.addRule(selector, rules, index);
}
}
// Use it!
addCSSRule(document.styleSheets[0], "header", "float: left");
这种方法可以应用于所有高级的浏览器,如果还是有担心的话,可以在调用时使用try-catch结构。
- 为Media queries插入样式规则
如果你需要插入media-queries的css样式规则,你只能使用第一个insertRule方法。
sheet.insertRule("@media only screen and (max-width : 1140px) { header { display: none; } }");
IE不支持insertRule函数,所以另一种方法是创建style标签节点,通过写入的方式来注入样式规则。
动态添加样式规则是有效且容易的。在下一个应用里尝试一下吧,你会发现这个真的很好用~
译文结束
[javascript][翻译]使用javascript添加css rule的更多相关文章
- JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能
摘要: 理解浏览器渲染. 原文:JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这是专门探索 J ...
- [书籍翻译] 《JavaScript并发编程》第一章 JavaScript并发简介
> 本文是我翻译<JavaScript Concurrency>书籍的第一章,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript并 ...
- [书籍翻译] 《JavaScript并发编程》第五章 使用Web Workers
本文是我翻译<JavaScript Concurrency>书籍的第五章 使用Web Workers,该书主要以Promises.Generator.Web workers等技术来讲解Ja ...
- [书籍翻译] 《JavaScript并发编程》第七章 抽取并发逻辑
本文是我翻译<JavaScript Concurrency>书籍的第七章 抽取并发逻辑,该书主要以Promises.Generator.Web workers等技术来讲解JavaScrip ...
- [书籍翻译] 《JavaScript并发编程》第六章 实用的并发
本文是我翻译<JavaScript Concurrency>书籍的第六章 实用的并发,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript ...
- [书籍翻译] 《JavaScript并发编程》第四章 使用Generators实现惰性计算
本文是我翻译<JavaScript Concurrency>书籍的第四章 使用Generators实现惰性计算,该书主要以Promises.Generator.Web workers等技术 ...
- [书籍翻译] 《JavaScript并发编程》第三章 使用Promises实现同步
本文是我翻译<JavaScript Concurrency>书籍的第三章 使用Promises实现同步,该书主要以Promises.Generator.Web workers等技术来讲解J ...
- [书籍翻译] 《JavaScript并发编程》 第二章 JavaScript运行模型
本文是我翻译<JavaScript Concurrency>书籍的第二章 JavaScript运行模型,该书主要以Promises.Generator.Web workers等技术来讲解J ...
- 在页面中添加两个 <select> 标签,用来显示年份和月份;同时添加两个 <ul> 标签,一个用来显示星期,另一个用来显示日期 在 JavaScript 脚本中动态添加年份和月份,获取当前日期的年份
查看本章节 查看作业目录 需求说明: 使用 JavaScript 中的 Date 对象,在页面上显示一个万年历.选择不同的年份和月份,在页面中显示当前月的日历 实现思路: 在页面中添加两个 <s ...
随机推荐
- OpenGL 画高斯随机函数
高斯函数代码 const float CFFTOceanShader::_getGaussianRandomFloat() const { float u1 = rand() / (float)RAN ...
- PyQt5系列教程(三)用py2exe进行程序打包
软硬件环境 Windows 10 Python 3.4.2 PyQt5 Py2exe 前言 在我们开发了完整的PyQt5项目后,一般都会将其打包成exe文件,方便其他人使用.今天我们就用Py2exe这 ...
- [译]作为一个web开发人员,哪些技术细节是在发布站点前你需要考虑到的
前日在cnblogs上看到一遍文章<每个程序员都必读的12篇文章>,其中大多数是E文的. 先译其中一篇web相关的”每个程序员必知之WEB开发”. 原文: http://programme ...
- Selenium Webdriver——Xpath轴定位(preceding)
1.preceding-sibling 选取当前节点之前的所有同级节点 text=出发之前的同级节点: 2.preceding 选取当前节点开始标签之前的所有节点 text=出发节点标签之前的所有i ...
- CommonDialog控件
'要先单击“工程-部件”,显示“部件”对话框,将“Microsoft Common Dialog control 6.0(SP6)”选中,在工具栏就多出了一个CommonDialog控件图标,将其添加 ...
- SystemColors 成员
名称 说明 ActiveBorder 获取 Color 结构,它是活动窗口边框的颜色. ActiveCaption 获取 Color 结构,它是活动窗口标题栏的背景色. ActiveCaptionTe ...
- 新手C#面向对象的学习2018.08.06
class Person//声明一个Person类 { //类中的声明与Main中不同,类中声明的是字段而不是函数. public string gender; public string name= ...
- interrupt()方法的简单理解
interrupt() 方法只是改变中断状态而已,它不会中断一个正在运行的线程.这一方法实际完成的是,给受阻塞的线程发出一个中断信号,这样受阻线程就得以退出阻塞的状态.更确切的说,如果线程被Objec ...
- 基础知识 一个工具给win7 win10的同学 或者MAC 可以跳过
- Liunx下如何使用kettle
在windows下完成所有操作, 把xxx.ktr上传到liunx, Pan.sh xxx.ktr 就完成了