最新消息:网站旨在学习交流,转载文章会尽力标明出处,如有侵权行为请联系(联系方式见页面底部)本站删除

使用JavaScript动态添加CSS样式规则!

网站建设 爱立排 来源:Searcheo 3浏览 0评论

现在Web应用中有大量的JavaScript代码,而我们也一直在追寻各种使他们更快的解决方案。

我们通过 事件代理(event delegation) 让事件监听更高效,

我们利用 函数降频技术(function debouncing) 来限制一段时间内给定方法被调用的次数。

我们使用 JavaScript加载器 来加载我们确实需要的那部分资源,等等。

还有一种方式,可以让我们的页面更加的快速和高效.那就是直接通过JS动态地添加和删除样式表中的某些样式,用来取代不断地查询DOM元素,并应用各种样式。下面是它的工作原理。

获取样式表你可以选择任意的样式表来添加样式规则。如果你有确定的样式表,则可以在HTML页面中给 <link> 或 <style> 标签添加ID属性,然后直接通过这个DOM元素的 sheet 属性就可以取得 CSSStyleSheet 对象。样式表也可以通过 document.styleSheets 遍历到:

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片

    //返回一个类似数组的(Array-like)样式列表StyleSheetList

    varsheets=document.styleSheets;

    /*

    返回值类似下面这样:

    StyleSheetList

    {

    0:CSSStyleSheet,

    1:CSSStyleSheet,

    2:CSSStyleSheet,

    3:CSSStyleSheet,

    4:CSSStyleSheet,

    length:5,

    item:function

    }

    */

    //获取第一个sheet,先不管media属性

    varsheet=document.styleSheets[0];

需要特别注意的是样式表的media属性 —— 当你想在屏幕上显示的时候,你肯定不能把CSS规则加到打印样式表中。你可以仔细的看一下CSSStyleSheet对象的属性信息:

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片

    //控制台输出第一个样式表的信息

    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"

    */

    //获取媒体类型(mediatype)

    console.log(document.styleSheets[0].media.mediaText)

    /*

    返回值可能是:

    "all"或者"print"或者是其他应用到此样式表的media

    */

在各种情况下,你肯定都有办法来获取到要添加规则的样式表。创建一个新样式表在许多情况下,最好的方法可能是创建一个新的 <style> 元素来存放这些动态规则。这也很简单:

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片

    varsheet=(function(){

    //创建<style>标签

    varstyle=document.createElement("style");

    //可以添加一个媒体(/媒体查询,mediaquery)属性

    //style.setAttribute("media","screen")

    //style.setAttribute("media","onlyscreenand(max-width:1024px)")

    //对WebKithack:(

    style.appendChild(document.createTextNode(""));

    //将<style>元素加到页面中

    document.head.appendChild(style);

    returnstyle.sheet;

    })();

悲剧的是WebKit需要一点hack手段才能正确创建,但我们只需要关心这个sheet。插入规则在早期版本的IE中 Stylesheets 的 insertRule方法并不可用,虽然现在这是规则注入的标准。insertRule 方法需要编写整个CSS规则,和在样式表中是一样的写法:

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片

    sheet.insertRule("header{float:left;opacity:0.8;}",1);


个JavaScript API方法虽然看起来有点土,但它确实就是这样运行的。第二个参数 index
表示要插入规则的位置(索引)。这也是非常有用的,这样你就可以插入同样的规则/代码,这可以让靠后的规则生效。默认的index是 -1
,代表整个集合的末尾。如果想要有额外的/懒惰控制规则,你也可以添加 !important 标记到某条规则后,以避免索引的问题。添加规则 —— 非标准的 addRule 方法CSSStyleSheet 对象有一个 addRule 方法,允许你注册CSS规则到样式表中。 addRule 方法接受三个参数: 第一个参数是选择器(selector)、第二个参数是CSS规则代码, 第三个则是从0开始的整数索引,表示样式的位置(在同一个选择器中):

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片

    sheet.addRule("#myListli","float:left;background:red!important;",1);

addRule方法的返回值总是 -1,所以这个值并没有什么实际意义.记住,这种方式的优点在于,从页面添加的元素自动拥有了应用于他们的样式,也就是说你不必将它们添加到具体的元素上,而是直接注入到页面中。当然效率更高!安全应用规则因为并不是所有的浏览器都支持 insertRule 方法, 所以最好创建一个包装函数来处理规则应用。下面是一个快速的土方法:

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片

    functionaddCSSRule(sheet,selector,rules,index){

    if("insertRule"insheet){

    sheet.insertRule(selector+"{"+rules+"}",index);

    }

    elseif("addRule"insheet){

    sheet.addRule(selector,rules,index);

    }

    }

    //使用方式

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

这个工具方法应该涵盖了新增style规则的所有情况。如果你担心在应用中出错, 那么应该将该方法的代码用一个 try{} catch(e){} 块包起来。插入媒体查询规则媒体查询规则的添加有两种方式。第一个是使用标准 insertRule 方法:

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片

    sheet.insertRule(

    "@mediaonlyscreenand(max-width:1140px){header{display:none;}}"

    );

当然,因为IE老版本不支持 insertRule,所以另一种方法就是创建一个 STYLE 元素,并指定适当的 media 属性,然后将样式添加到新的样式表中。这可能需要使用多个 STYLE 元素,但也是很容易的。我可能会创建一个对象,指定媒体查询以及索引,并那样创建/获取他们。动态添加规则到样式表是高效的手段,可能比你想象的还要简单。请记住这种方案,可能在你的下一个大应用中需要使用,因为它能在代码和元素处理这两方面避免你掉进坑里。

原文链接:Add Rules to Stylesheets with JavaScript

转载请注明:爱立排 » 使用JavaScript动态添加CSS样式规则!

猜你喜欢

avatar
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址