DOM《CSS操作》

163 阅读6分钟

HTML元素的Style属性

  • 操作CSS样式最简单的方法就是使用网页元素节点的xxxAttribute()方法,直接读写或删除style属性。
  • style本身是一个部署了CSSSstyleDeclaration接口的对象,可以直接读写个别属性。但返回的是行内样式,并不是该元素的全部样式。
div.setAttribute(
  'style',
  'background-color:red;' + 'border:1px solid black;'
);
div.getAttribute('style')  // 'background-color:red;border:1px solid black;'


div.style    //  CSSStyleDeclaration {...}
div.style.fontSize = '18px';

CSSStyleDeclaration接口

  • 用来操作元素的样式,可以直接读写 CSS 的样式属性。该对象是一个活的对象,任何对于样式的修改都会实时反映到这个实例上面。以下三个地方部署了这个接口:

    • 元素节点的style属性。
    • CSSStyle实例的style属性。
    • window.getComputedStyle()的返回值。
var divStyle = document.querySelector('div').style;

divStyle.backgroundColor = 'red';
divStyle.border = '1px solid black';
divStyle.height = '100px';
divStyle.fontSize = '10em';

divStyle.backgroundColor // red
divStyle.border // 1px solid black
divStyle.height // 100px

实例属性

cssText

  • 用来读写当前元素节点的所有行内样式文本,可读写。
var divStyle = document.querySelector('div').style;
divStyle.cssText = 'background-color: red;'
  + 'border: 1px solid black;'
  + 'height: 100px;'
  + 'width: 100px;';
  
divStyle.cssText = '';  // 删除元素的所有行内样式

length

  • 返回一个整数,表示当前元素节点包含了多少条行内样式。
<div id="myDiv" style="height: 1px;width: 100%;background-color: #CA1;"></div>

var myDiv = document.getElementById('myDiv');
myDiv.style.length // 3

parentRule

  • 返回当前规则所属的那个样式块(CSSRule实例)。如果不存在所属的样式块返回null
var declaration = document.styleSheets[0].rules[0].style;
declaration.parentRule === document.styleSheets[0].rules[0]  // true

实例方法

getPropertyPriority()

  • 接受CSS样式的属性名作为参数,返回字符串,表示有没有设置important优先级。如果有就返回important,否则返回空字符串。
<div id="myDiv" style="margin: 10px!important; color: red;"></div>

var style = document.getElementById('myDiv').style;
style.margin     // "10px"
style.getPropertyPriority('margin') // "important"
style.getPropertyPriority('color')  // ""

getPropertyValue()

  • 接受CSS样式属性名作为参数,返回字符串,表示该属性的属性值。
<div id="myDiv" style="margin: 10px!important; color: red;"></div>

var style = document.getElementById('myDiv').style;
style.margin                     // "10px"
style.getPropertyValue("margin") // "10px"

item()

  • 接受一个整数作为参数,返回该位置的CSS属性名。
<div id="myDiv" style="margin: 10px!important; color: red;"></div>

var style = document.getElementById('myDiv').style;
style.item(0) // color  CSSStyleDeclaration对象自带排序
style  // CSSStyleDeclaration {0: 'color', 1: 'margin-top', 2: 'margin-right', 3: 'margin-bottom', 4: 'margin-left', ...}

removeProperty()

  • 接受一个属性名作为参数,在CSS规则里面移除这个属性,返回这个属性原来的值。
<div id="myDiv" style="color: red; background-color: white;">111</div>

document.getElementById('myDiv').style.removeProperty('color');  // 'red'
// 结果:
<div id="myDiv" style="background-color: white;">

setProperty()

  • 用来设置新的CSS属性,没有返回值。三个参数:参数一是属性名,必需的。参数二是属性值,可选。省略则为空字符串。参数三是优先级,可选。唯一合法值是important,表示CSS中的!important
<div id="myDiv" style="color: red; background-color: white;">111</div>

document.getElementById('myDiv').style.setProperty('border', '1px solid #000');
// 结果:
<div id="myDiv" style="color: red; background-color: white; border: 1px solid rgb(0, 0, 0);">111</div>

CSS模块的侦测

  • 不同浏览器的不同版本,对CSS模块的支持情况都不一样。有时需要知道当前浏览器是否支持某个模块。一个普遍的方法是,判断元素的style对象的某个属性值是否为字符串。
  • 如果CSS属性确实存在,会返回一个字符串。即使该属性实际上并未设置,也会返回一个空字符串。如果该属性不存在,则会返回undefined
document.body.style['maxWidth']     // ""        支持
document.body.style['maximumWidth'] // undefined 不支持

CSS对象

  • 浏览器原生提供CSS对象,为JS操作CSS提供一些工具方法。目前有两个静态方法。

escape()

  • 用于转义CSS选择器里面的特殊字符。
<div id="foo#bar">

document.querySelector('#foo#bar') // null 因为 # 字符在CSS选择器里有特殊含义
document.querySelector('#' + CSS.escape('foo#bar'))  // <div id="foo#bar"></div>

supports()

  • 返回一个布尔值,表示当前环境是否支持某一句CSS规则。参数有两种写法,一种是第一个参数是属性名,第二个参数是属性值;另一种是整个参数就是一行完整的 CSS 语句。
// 第一种写法
CSS.supports('transform-origin', '5px') // true

// 第二种写法
CSS.supports('display: table-cell') // true

window.getComputedStyle()

  • 返回浏览器计算后得到的最终规则。接受一个节点对象作为参数,返回CSSStyleDeclaration实例。包含了指定节点的最终样式信息。还可以接受第二个参数,表示当前元素的伪元素。
var div = document.querySelector('div');
var styleObj = window.getComputedStyle(div);
styleObj    // CSSStyleDeclaration {0:...}
styleObj.backgroundColor  // 'rgba(0, 0, 0, 0)'

var result = window.getComputedStyle(div, ':before');

伪元素

  • 通过CSS向DOM添加的元素,主要是通过:before:after选择器生成,然后用content属性指定为元素的内容。
#test:before {
  content: 'Before ';
  color: #FF0;
}

<div id="test">Test content</div>
  • 节点元素的style对象无法读写伪元素的样式,但window.getComputedStyle()可以。
var test = document.querySelector('#test');
var result = window.getComputedStyle(test, ':before').content;  // "Before "
var color = window.getComputedStyle(test, ':before').getPropertyValue('color');  // rgb(255, 255, 0)

StyleSheet接口

  • StyleSheet接口代表网页的一张样式表,包括<link>元素加载的样式表和<style>元素内嵌的样式表。
  • 此接口不仅包含网页样式表,还包括XML文档的样式表,所以它有一个子类CSSStyleSheet表示网页的CSS样式表,实际返回的样式表实例其实是CSSStyleSheet实例。
  • document对象的styleSheets属性可以返回当前页面的所有StyleSheetList实例(即所有样式表),返回一个类数组。
document.styleSheets; // StyleSheetList {0: CSSStyleSheet, 1: CSSStyleSheet, 2: CSSStyleSheet, length: 3}

实例属性

disabled

  • 返回一个布尔值,表示该样式表是否处于禁用状态。手动设置为true等同于在<link>元素里,将这张样式表设为alternate stylesheet,即该样式表不会生效。
document.styleSheets[1].disabled = true  // 禁用样式

href

  • 返回样式表的网址。对于内嵌样式表,该属性返回null。只读。
document.styleSheets[0].href // 'https://wangdoc.com/javascript/assets/css/app.min.css'

media

  • 返回一个类数组(MediaList实例),成员是表示适用媒介的字符串。表示当前样式表是用于屏幕(scrren)、打印(print)、手持设备(handheld)、所有媒介适用(all)。只读。默认值为screen
document.styleSheets[0].media  // MediaList {length: 0, mediaText: ''}
document.styleSheets[0].media.mediaText  // ''

document.styleSheets[0].media.appendMedium('handheld');  // 添加媒介
document.styleSheets[0].media.deleteMedium('print');  // 删除媒介

title

  • 返回样式表的title属性。

type

  • 返回样式表的type属性,通常是text/css

parentStyleSheet

  • CSS的@import命令允许在样式表中加载其他子样式表,此属性返回父样式表。如果当前样式表是顶层样式表,则返回null

ownerNode

  • 返回StyleSheet对象所在的DOM节点,通常是<link><style>,对于那些由其他样式表引用的样式表,则返回null
document.styleSheets[0].ownerNode // <link rel="stylesheet" href="../assets/css/app.min.css">

cssRules

  • 指向一个类数组(CSSRuleList实例),里面每一个成员就是当前样式表的一条CSS规则。
// CSS对应的字符串
document.styleSheets[0].cssRules[0].cssText  // "p { line-height: 1.4em; color: blue; }"

// 指向style对象,用来读写具体的CSS命令
document.styleSheets[0].cssRules[0].style  // CSSStyleDeclaration {....}

ownerRule

  • 有些样式表是通过@import规则输入的,它的ownerRule属性会返回一个CSSRule实例,代表那行@import规则。如果当前样式表不是通过@import引入的,ownerRule属性返回null

实例方法

insertRule()

  • 用于在当前样式表插入一个新的CSS规则。两个参数,参数一表示CSS规则的字符串,只能有一条;参数二是该规则在样式表的插入位置(从0开始),可选,默认为0。
var sheet = document.querySelector('#styleElement').sheet;
sheet.insertRule('#block { color: white }', 0);
sheet.insertRule('p { color: red }', 1);

deleteRule()

  • 在样式表里移除一条规则,参数是该条规则在cssRules对象中的位置。没有返回值。
document.styleSheets[0].deleteRule(1);

CSSRuleList接口

  • 类数组,表示一组CSS规则,成员都是CSSRule实例。一般是通过StyleSheet.cssRules属性获取。
let cssRules = document.styleSheets[0].cssRules   // CSSRuleList {0:...}
cssRules[0]  // CSSStyleRule {...}

CSSRule接口

  • 一条CSS规则包括两个部分:CSS选择器样式声明。JS通过CSSRule接口操作CSS规则。一般通过CSSRuleList接口获取CSSRule实例。

添加样式表

  • 添加内置样式表<style>节点
var style = (function () {
  var style = document.createElement('style');
  document.head.appendChild(style);
  return style;
})();
style.sheet.insertRule('.foo{color:red;}', 0);
  • 添加外部样式表<link>节点
;(function () {
    var linkElm = document.createElement('link');
    linkElm.setAttribute('rel', 'stylesheet');
    linkElm.setAttribute('type', 'text/css');
    linkElm.setAttribute('href', 'reset-min.css');

    document.head.appendChild(linkElm);
})();