JavaScript实现动态创建CSS样式规则方案

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

1.我们通过 事件代理(event delegation) 让事件监听更高效,
2.我们利用 函数降频技术(function debouncing)来限制一段时间内给定方法被调用的次数,请参考:如何防止事件函数的高频触发(中文翻译)
3.我们使用 JavaScript加载器 来加载我们确实需要的那部分资源,等等。

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

获取样式表

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

代码如下:

// 返回一个类似数组的(Array-like)样式列表 StyleSheetList
var sheets = document.styleSheets;

/*
返回值类似下面这样:

StyleSheetList
{
    0: CSSStyleSheet,
    1: CSSStyleSheet,
    2: CSSStyleSheet,
    3: CSSStyleSheet,
    4: CSSStyleSheet,
    length: 5,
    item: function
}
*/

// 获取第一个sheet, 先不管 media属性
var sheet = document.styleSheets[0];

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

代码如下:

// 控制台输出第一个样式表的信息
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"
*/

// 获取媒体类型(media type)
console.log(document.styleSheets[0].media.mediaText)
/*
返回值可能是:
    "all" 或者 "print" 或者是其他应用到此样式表的 media
*/

在各种情况下,你肯定都有办法来获取到要添加规则的样式表。

创建一个新样式表

在许多情况下,最好的方法可能是创建一个新的 <style> 元素来存放这些动态规则。这也很简单:

代码如下:

var sheet = (function() {
    // 创建 <style> 标签
    var style = document.createElement("style");

// 可以添加一个媒体(/媒体查询,media query)属性
    // style.setAttribute("media", "screen")
    // style.setAttribute("media", "only screen and (max-width : 1024px)")

// 对WebKit hack :(
    style.appendChild(document.createTextNode(""));

// 将 <style> 元素加到页面中
    document.head.appendChild(style);

return style.sheet;
})();

悲剧的是WebKit需要一点hack手段才能正确创建,但我们只需要关心这个sheet。

插入规则

在早期版本的IE中 Stylesheets 的 insertRule方法并不可用,虽然现在这是规则注入的标准。insertRule 方法需要编写整个CSS规则,和在样式表中是一样的写法:

代码如下:

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

这个JavaScript API方法虽然看起来有点土,但它确实就是这样运行的。第二个参数 index 表示要插入规则的位置(索引)。这也是非常有用的,这样你就可以插入同样的规则/代码,这可以让靠后的规则生效。默认的index是 -1 ,代表整个集合的末尾。如果想要有额外的/懒惰控制规则,你也可以添加 !important 标记到某条规则后,以避免索引的问题。

添加规则 —— 非标准的 addRule 方法

CSSStyleSheet 对象有一个 addRule 方法,允许你注册CSS规则到样式表中。 addRule 方法接受三个参数: 第一个参数是选择器(selector)、第二个参数是CSS规则代码, 第三个则是从0开始的整数索引,表示样式的位置(在同一个选择器中):

代码如下:

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

addRule方法的返回值总是 -1,所以这个值并没有什么实际意义.
记住,这种方式的优点在于,从页面添加的元素自动拥有了应用于他们的样式,也就是说你不必将它们添加到具体的元素上,而是直接注入到页面中。当然效率更高!

安全应用规则

因为并不是所有的浏览器都支持 insertRule 方法, 所以最好创建一个包装函数来处理规则应用。下面是一个快速的土方法:

代码如下:

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);
    }
}

// 使用方式
addCSSRule(document.styleSheets[0], "header", "float: left");

这个工具方法应该涵盖了新增style规则的所有情况。如果你担心在应用中出错, 那么应该将该方法的代码用一个 try{} catch(e){} 块包起来。

插入媒体查询规则

媒体查询规则的添加有两种方式。第一个是使用标准 insertRule 方法:

代码如下:

sheet.insertRule(
  "@media only screen and (max-width : 1140px) { header { display: none; } }"
  );

当然,因为IE老版本不支持 insertRule,所以另一种方法就是创建一个 STYLE 元素,并指定适当的 media 属性,然后将样式添加到新的样式表中。这可能需要使用多个 STYLE 元素,但也是很容易的。我可能会创建一个对象,指定媒体查询以及索引,并那样创建/获取他们。

动态添加规则到样式表是高效的手段,可能比你想象的还要简单。请记住这种方案,可能在你的下一个大应用中需要使用,因为它能在代码和元素处理这两方面避免你掉进坑里。

(0)

相关推荐

  • js改变css样式的三种方法推荐

    共用代码: <div id="div"> this is a div </div> var div=document.getElementById('div'); 第一种:用cssText div.style.cssText='width:250px;height:250px;border:1px red solid;'; 第二种:用setProperty() div.style.setProperty('width','250px'); div.style.s

  • 用JavaScript动态建立或增加CSS样式表的实现方法

    1.简单的方法,不管不顾,直接这样就可以: document.createStyleSheet().cssText = '标签{color:red;' + // 这个注释只在当前JS中帮助理解,并不会写入CSS中 'width:300px;height:150px}' + '.类名{--}' + '#ID们{--}' ; //完活.我喜欢分号这样写,和指令书写的起始位置对齐比较好一点,尤其是后面有其它语句的时候. 2.完善一点的方法,防止重复添加,可以通过添加样式表ID并对其判断来实现: if

  • JavaScript改变CSS样式的方法汇总

    JavaScript允许你即时的改变CSS样式,这样就可以将用户的眼球吸引到你想他们关注的地方上,并且提供较好的交互体验给力 . JavaScript修改CSS有4种方法: 修改节点style(内联样式): 改变节点class或id: 写入新的css: 替换页面中的样式表. 个人不建议使用后两种方法,几乎所有的功能都可以通过前两种方式实现,并且代码更加清晰.易理解. 后面还会说说如何获取元素的真实样式和一个表单中的注意事项. 1.修改节点style(内联样式) 这种方法权重是最高的,直接写在节点

  • JS判断移动端访问设备并加载对应CSS样式

    JS判断不同web访问环境,主要针对移动设备,提供相对应的解析方案(判断设备代码直接copy腾讯网的) 复制代码 代码如下: // 判断是否为移动端运行环境 if(/AppleWebKit.*Mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alcatel|BIRD|DBTEL|Dopod|PHILIPS|HAIER|LENOVO|MOT-|Nokia|SonyEricsson|SIE-

  • 如何用JavaScript实现动态修改CSS样式表

    看过我写的<用JavaScript动态建立或增加CSS样式表的实现方法>之后,你就很容易想明白如何修改CSS样式表了. 正好今天在论坛碰到一位朋友问这样的一个问题: <style> .ls{width=120px;} </style> <script> //在这里加一句来改变.ls中width的值,如何写 </script> 有的朋友回答:"如果使用.ls的对象很多的话,用JS确实不方便, jquery方便,$(".ls&qu

  • javascript 动态修改css样式方法汇总(四种方法)

    在很多情况下,都需要对网页上元素的样式进行动态的修改.在JavaScript中提供几种方式动态的修改样式,下面将介绍方法的使用.效果.以及缺陷. 1.使用obj.className来修改样式表的类名. 2.使用obj.style.cssTest来修改嵌入式的css. 3.使用obj.className来修改样式表的类名. 4.使用更改外联的css文件,从而改变元素的css 下面是一段html代码和css代码用来解释上面方法的区别的. CSS .style1{margin:10px auto ;b

  • JavaScript实现动态创建CSS样式规则方案

    现在Web应用中有大量的JavaScript代码,而我们也一直在追寻各种使他们更快的解决方案. 1.我们通过 事件代理(event delegation) 让事件监听更高效, 2.我们利用 函数降频技术(function debouncing)来限制一段时间内给定方法被调用的次数,请参考:如何防止事件函数的高频触发(中文翻译) 3.我们使用 JavaScript加载器 来加载我们确实需要的那部分资源,等等. 还有一种方式,可以让我们的页面更加的快速和高效.那就是直接通过JS动态地添加和删除样式表

  • JavaScript动态添加css样式和script标签

    [动态添加css样式] <html> <head> <script type="text/javascript"> window.onload=function(){ var head=document.getElementsByTagName('head')[0]; //获取到head元素 var link=document.createElement('link'); //创建link元素节点,也就是link标签 link.rel="s

  • 用JS动态设置CSS样式常见方法小结(推荐)

    用JS来动态设置CSS样式,常见的有以下几种 1. 直接设置style的属性 某些情况用这个设置 !important值无效 如果属性有'-'号,就写成驼峰的形式(如textAlign) 如果想保留 - 号,就中括号的形式 element.style['text-align'] = '100px'; element.style.height = '100px'; 2. 直接设置属性(只能用于某些属性,相关样式会自动识别) element.setAttribute('height', 100);

  • jquery实现动态改变css样式的方法分析

    本文实例讲述了jquery实现动态改变css样式的方法.分享给大家供大家参考,具体如下: jquery 几乎成了现在开发WEB应用的标准JS库,这与其简单性和易用性是分不开的.作为一个后端开发人员,要做一些前端页面时,CSS 样式的控制是少不了需要掌握的.如果是静态的CSS,当然是可以直接写上去的,但有些界面是需要一些动态效果的,比如颜色变化,字体大小变化,甚至DIV 的隐藏于现实等,这些都需要用javascript 动态控制其CSS样式,下面就常用的jquery 控制 css 样式的方法做一个

  • 基于JavaScript实现动态创建表格和增加表格行数

    在工作,项目需求中,有时候表格的行数不能够满足我们的需求,这时需要我们动态的增加表格的行数,下面小编通过一段代码实例给大家介绍js创建表格和增加表格的行数的方法,并且还实现了隔行变色功能.对此感兴趣的朋友可以参考一下代码: js代码如下所示: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>动态操作表格</title> </head>

  • javascript元素动态创建实现方法

    本文实例讲述了javascript元素动态创建实现方法.分享给大家供大家参考.具体分析如下: document.write只能在页面加载过程中才能动态创建 可以调用document的createElement方法来创建具有指定标签的DOM对象,然后通过调用元素的appendChild方法将 新创建元素添加到相应的元素下 举例如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-e

  • vuejs实现标签选项卡动态更改css样式的方法

    html <ul class="header-list"> <li v-cloak v-for="(item,index) in headerList" v-on:click="selectMainTheme(index)"><a href="java:;" rel="external nofollow" :class="{'active':idx == index}

  • 详解react的两种动态改变css样式的方法

    第一种:动态添加class,以点击按钮让文字显示隐藏为demo import React, { Component, Fragment } from 'react'; import './style.css'; class Demo extends Component{ constructor(props) { super(props); this.state = { display: true } this.handleshow = this.handleshow.bind(this) thi

  • vue中如何动态设置css样式的hover

    目录 vue动态设置css样式的hover vue使用hover.css动画 vue动态设置css样式的hover 1.定义不同的颜色数组 colorList: ['#4cb352', '#5bc2d3', '#ffc23f', 'pink', '#872822'],//课件标题颜色 2.html数据遍历-自定义element-走马灯高度+定义css变量-yf-border-color  <div             v-for="(item, index) in listData&q

随机推荐