[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[0];

  在我们选取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标签节点,通过写入的方式来注入样式规则。

  动态添加样式规则是有效且容易的。在下一个应用里尝试一下吧,你会发现这个真的很好用~

译文结束

时间: 2024-11-06 02:01:38

[javascript][翻译]使用javascript添加css rule的相关文章

Rails 添加css javascript 结合easyui

<% content_for :header_tags do  %>    <%=stylesheet_link_tag 'bar.css', :plugin=>'redmine_standard' %>    <%=javascript_include_tag 'bar.css', :plugin=>'redmine_standard' %><%    end  %> <% content_for :header_tags do  %&g

[书籍翻译] 《JavaScript并发编程》 第二章 JavaScript运行模型

本文是我翻译<JavaScript Concurrency>书籍的第二章 JavaScript运行模型,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript并发编程方面的实践. 完整书籍翻译地址:https://github.com/yzsunlei/javascript_concurrency_translation .由于能力有限,肯定存在翻译不清楚甚至翻译错误的地方,欢迎朋友们提issue指出,感谢. 本书第一章我们探讨了JavaScri

[书籍翻译] 《JavaScript并发编程》第五章 使用Web Workers

本文是我翻译<JavaScript Concurrency>书籍的第五章 使用Web Workers,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript并发编程方面的实践. 完整书籍翻译地址:https://github.com/yzsunlei/javascript_concurrency_translation .由于能力有限,肯定存在翻译不清楚甚至翻译错误的地方,欢迎朋友们提issue指出,感谢. Web workers在Web浏览器中

[书籍翻译] 《JavaScript并发编程》第六章 实用的并发

本文是我翻译<JavaScript Concurrency>书籍的第六章 实用的并发,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript并发编程方面的实践. 完整书籍翻译地址:https://github.com/yzsunlei/javascript_concurrency_translation .由于能力有限,肯定存在翻译不清楚甚至翻译错误的地方,欢迎朋友们提issue指出,感谢. 在上一章中,我们大致学习了Web workers的基本

[书籍翻译] 《JavaScript并发编程》第七章 抽取并发逻辑

本文是我翻译<JavaScript Concurrency>书籍的第七章 抽取并发逻辑,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript并发编程方面的实践. 完整书籍翻译地址:https://github.com/yzsunlei/javascript_concurrency_translation .由于能力有限,肯定存在翻译不清楚甚至翻译错误的地方,欢迎朋友们提issue指出,感谢. 到本书这里,我们已经在代码中明确地模拟了并发问题.使

JavaScript基础--事件驱动和访问CSS技术(十)

1.原理: 2.快速入门案例 js中的事件主要分为4种: 案例:监听鼠标点击事件,并能够显示鼠标点击的位置x,y <script language="javascript" type="text/javascript"> function test1(e){ window.alert('x='+e.clientX+'y='+e.clientY); } function test2(e){ window.alert('x='+e.clientX+'y='+

Javascript DOM 03 表格添加、删除 + 搜索

获取 tBodies.tHead.tFoot.rows.cells 隔行变色 鼠标移入高亮 添加.删除一行 DOM方法的使用  添加.删除 1 <script> 2 window.onload=function (){ 3 /*var str='abcdef'; 4 alert(str.search('g')); //找到并且返回字符串出现的位置,如果没找到-1 5 */ 6 /* 7 var str='abc 123 ert'; 8 var arr=str.split(' '); 9 ale

javascript 利用 - 枚举思想 - 添加地名的一个小例子

利用枚举思想来添加地名,主要功能是:判断点击a标签(即当前的地名)如果在ul的li不存在的话那么就添加,有则不添加,而且还提供了相应的排序功能... HTML代码: <div id="china"> <a href="javascript:;">广州</a> <a href="javascript:;">深圳</a> <a href="javascript:;"

构建基于Javascript的移动CMS——添加滑动

在和几个有兴趣做移动CMS的小伙伴讨论了一番之后,我们觉得当前比较重要的便是统一一下RESTful API.然而最近持续断网中,又遭遇了一次停电,暂停了对API的思考.在周末无聊的时光了看了<人间失格>,又看了会<一个人流浪,不必去远方>.开始思考所谓的技术以外的事情,或许这将是下一篇讨论的话题. 正在我对这个移动CMS的功能一筹莫展的时候,帮小伙伴在做一个图片滑动的时候,便想着将这个功能加进去,很顺利地找到了一个库. 移动CMS滑动 我们所需要的两个功能很简单 当用户向右滑动的时