Part ONE: Interface introduction
First, there are three ways to define styles in HTML:
- through
link
The element contains external stylesheet files - use
style
The element defines an embedded style - use
style
Attributes define styles for specific elements
The DOM2-level module provides a set of apis around these three application style mechanisms. Understanding this API will help you understand how to manipulate CSS with JS. There are many types of interfaces. The diagram below:
MDN
Interfaces are regular, and it’s hard to memorize them by rote, but it’s easier to understand interfaces by looking at the three ways they’re styled in HTML.
1.1 CSSStyleSheet
Style sheet object
The interface with StyleSheet in its name stands for StyleSheet. The CSSStyleSheet interface type represents a stylesheet. Includes external stylesheets contained through the link element and stylesheets defined in the
element. The CSSStyleSheet interface inherits StyleSheet. StyleSheet can be used as a base interface to define non-CSS stylesheets.
1.2 CSSRule
Style sheet rule object
An interface with Rule in its name means Rule. The CSSRule object represents each rule in the stylesheet. CSSRule is actually a base type that many other types inherit from. The most common of these is the CSSStyleRule type, which represents style information.
All subtypes of CSSRule are as follows:
CSSCharsetRule
CSSConditionRule
CSSCounterStyleRule
CSSFontFeatureValuesRule
CSSGroupingRule
CSSImportRule
CSSKeyframeRule
CSSKeyframesRule
CSSMarginRule
CSSMediaRule
CSSNamespaceRule
CSSPageRule
CSSSupportsRule
CSSViewportRule
CSSFontFaceRule
CSSStyleRule
These rules rarely need to be accessed through scripts, and the most common is the CSSStyleRule type.
The following figure can deepen our understanding of the relationship between StyleSheet and CSSRule.
1.3 CSSStyleDeclaration
Object applied to the element style property
Any HTML element that supports the style feature has a corresponding style attribute in JavaScript. This style object is an instance of CSSStyleDeclaration. Contains all style information specified by the STYLE feature of HTML, but does not include styles that are layered with external or embedded style sheets.
We often use the htmlElement. style attribute to return the CSSStyleDeclaration object. The CSSStyleDeclaration object represents the style property of an element.
Part II:CSSStyleSheet
Type Interface Introduction
2.1 StyleSheet
Properties and methods supported by the type:
CSSStyleSheet inherits from StyleSheet, and StyleSheet acts as a base interface to define non-CSS stylesheets. The attributes inherited from the StyleSheet interface are as follows:
disabled
: A Boolean value indicating whether the stylesheet is disabled. This property is readable/writable, and setting this value to true disables the stylesheet.href
The URL of the stylesheet if the stylesheet is included; Otherwise, null.media
:ownerNode
: a pointer to the node that has the current style sheet, which may be passed in HTMLlink(HTMLLinkElement)
orstyle(HTMLStyleElement)
The introduction of. This property is null if the current stylesheet was imported by another stylesheet via @import. IE does not support this property.parentStyleSheet
: The current stylesheet is passed@import
In the case of imports, this property is a pointer to the stylesheet from which it was imported, otherwise null.title
: Value of the title property in ownerNode, otherwise null.type
: a string representing the style sheet type. For CSS stylesheets, this string is “type/ CSS “.
The CSSStyleSheet object is a set of read-only interfaces. Except for the disabled attribute.
2.2 CSSStyleSheet
Interface types support properties and methods:
In addition to inheriting the attributes of the StyleSheet interface, CSSStyleSheet also supports the following attributes and methods:
cssRules(rules)
: a collection of style rules contained in a stylesheet. IE does not support this property, but there is a similar onerules
Properties.ownerRule
: If the stylesheet is passed@import
Imported, this property is a pointer to the imported rule; Otherwise, the value is null. IE does not support this property.deleteRule(index)
: deletecssRules
A rule for a specified position in a collection. IE does not support this method, but does support a similar oneremoveRule()
Methods.insertRule(rule,index)
To:cssRules
Insert at the specified position in the collectionrule
A string. IE does not support this method, but does support a similar oneaddRule()
Methods.replace()
Build a stylesheet that does not allow external references.replaceSync()
Build a stylesheet that allows external references.
2.3 the use ofJavaScript
Accessing style sheets
One way to access a stylesheet
All styleSheets applied to documents are represented through the Document.stylesheets collection. The collection’s Length attribute tells you the number of stylesheets in the document, and each stylesheet is accessible through square bracket syntax or the item() method.
let sheet = null;
for(leti = 0, len = document.styleSheets.length; i < len; i++) { sheet = document.styleSheets[i]; console.log(sheet.href) }Copy the code
The code above prints the href attribute of each stylesheet used in the document (style elements contain stylesheets that do not have the href attribute).
Style sheet access method two
You can also retrieve the CSSStyleSheet object using the link or style element. The DOM specifies a property that contains a CSSStyleSheet object called sheet. All browsers except Internet Explorer support this property. IE supports styleSheet.
Stylesheet objects are available in different browsers:
function getStyleSheet(element){
returnelement.sheet || element.styleSheet; } / / the first < link / > element in the style sheet, if there are no returns empty HTMLCollection const link set = document. GetElementsByTagName ("link") [0];if(typeof link === 'object' && link.rel === 'stylesheet') {
const sheet = getStyleSheet(link);
}
Copy the code
If the link tag is not an imported CSS style, the sheet returns NULL.
Part III:CSSRule
Rule type interfaces
The CSSRule object represents each rule in the stylesheet. In fact, CSSRule is a base class type that can be inherited by a variety of other types, the most common of which is the CSSStyleRule type, which represents style information. (Other rules include @import, @font-face, @page, and @charset, but these rules rarely need to be accessed via scripts.) The CSSStyleRule object contains the following properties.
cssText
: Returns the text of the entire rule. The text returned may not be the same as the actual text in the stylesheet because of the way the browser handles the stylesheet internally; Safari always converts text to all lowercase. IE does not support this property.parentRule
If the current rule is an imported rule, this property references the imported rule. Otherwise, the value is null. IE does not support this property.parentStyleSheet
: Style sheet to which the current rule belongs. IE does not support this property.selectorText
: Returns the selector text for the current rule.style
A:CSSStyleDeclaration
Object through which you can set and get specific style values in rules.type
: Represents the constant value of the rule type. For style rules, this value is 1. IE does not support this property.styleMap
A:StylePropertyMap
Object.StylePropertyMap
Object provides a representation of a CSS declaration block that can be substitutedCSSStyleDeclaration
.
The cssText property of the CSSStyleRule object is similar to, but not identical to, the style.csstext property. The former contains the selector text and curly braces around the style information, while the latter contains only the style information (similar to the style.csstext element). In addition, cssText is read-only, and style.csstext can also be overridden.
Here is the result of getting the display of each attribute:
<style type="text/css">
.demo {
background-color: blue;
width: 100px;
height: 200px;
}
</style>
<script>
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules;
var rule = rules[0];
console.log(rule.selectorText); //.demo
console.log(rule.style.backgroundColor); //blue
console.log(rule.style.width); //100px
console.log(rule.style.height); //200px
//.demo { background-color: blue; width: 100px; height: 200px; }
console.log(rule.cssText);
//background-color: blue; width: 100px; height: 200px;
console.log(rule.style.cssText);
</script>
Copy the code
Using rule-style, you can determine the style information associated with a rule in the same way you determine the inline style information for an element. As with elements, style information can be modified in this way, as in the following example:
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules;
var rule = rules[0];
rule.style.backgroundColor = "red";
Copy the code
Changing the rule in this way affects all the elements on the page that apply to the rule. In other words, if you have two div elements with demo classes, the modified styles will apply to both elements.
3.1 Creating and Deleting Rules (CSSStyleSheet
Interface methods)
Create rules
DOM states that to add new rules to an existing stylesheet, you need to use the insertRule() method. This method takes two parameters: the text of the rule and an index indicating where to insert the rule.
var sheet = document.styleSheets[0];
sheet.insertRule("body { background-color: silver }", 0); / / IE does not supportCopy the code
IE8 and earlier support a similar method called addRule()
sheet.addRule("body"."background-color: silver", 0); // Only for IECopy the code
Insert rules into the stylesheet in a cross-browser fashion:
//insertRule(document.styleSheets[0], "body"."background-color: silver", 0);
function insertRule(sheet, selectorText, cssText, position){
if (sheet.insertRule){
sheet.insertRule(selectorText + "{" + cssText + "}", position);
} else if(sheet.addRule){ sheet.addRule(selectorText, cssText, position); }}Copy the code
The above example inserts a rule that changes the background color of the element. The inserted rule becomes the first rule in the stylesheet (at position 0) — the order of the rules is critical in determining the rules to be applied to the document after the cascade.
Delete rules
The method for deleting a rule from a stylesheet is deleteRule(), which takes one parameter: the location of the rule to be deleted. For example, delete the first rule in a stylesheet.
sheet.deleteRule(0);
Copy the code
A similar method supported by IE is called removeRule() :
sheet.removeRule(0); // Only for IECopy the code
Remove rules from the stylesheet in a cross-browser fashion:
//deleteRule(document.styleSheets[0], 0);
function deleteRule(sheet, index){
if (sheet.deleteRule){
sheet.deleteRule(index);
} else if(sheet.removeRule){ sheet.removeRule(index); }}Copy the code
Add rules and delete rules are not commonly used in Web development. Use them with caution.
Part IV:CSSStyleDeclaration
Access the style of the element directly
Any HTML element that supports the style feature has a corresponding style attribute in JavaScript. This is what we would normally write in an HTML element:
<div style="font-size:20px; color:red;"> container < / div >Copy the code
The style object above is an instance of CSSStyleDeclaration. Contains all style information specified by the STYLE feature of HTML, but does not include styles that are layered with external or embedded style sheets.
For CSS property names that use a dash (separating different terms, such as background-image), you must convert them to camel case. Here are a few examples:
CSS properties | JavaScript attribute |
---|---|
background-image |
style.backgroundImage |
color |
style.color |
font-family |
style.fontFamily |
var myDiv = document.getElementById("myDiv");
myDiv.style.backgroundColor = "red";
myDiv.style.width = "100px";
myDiv.style.border = "1px solid black";
Copy the code
One CSS property that cannot be converted directly is float. Because float is a reserved word in JavaScript, it cannot be used as an attribute name. The DOM2-level style specification specifies that the corresponding property name on the style object should be cssFloat. Internet Explorer supports styleFloat. You can determine which floats are supported by the current browser in the following way:
const support = (function(){
const div = document.createElement("div");
div.style.cssText = "float:left;";
letsupport = { cssFloat: !! div.style.cssFloat }return support;
})()
const floatReal = support.cssFloat ? 'cssFloat' : 'styleFloat';
Copy the code
Document. documentMode can also be used to judge:
const floatReal = Number(document.documentMode) < 9 ? 'styleFloat' : 'cssFloat'
Copy the code
As long as you get a reference to a valid DOM element, you can style it at any time using JavaScript:
var myDiv = document.getElementById("myDiv");
myDiv.style.width = "100px";
myDiv.style.border = "1px solid black";
Copy the code
All measures must specify a unit of measure. Here is an example of setting the style attribute of an element:
function setStyle(element, styles) {
function is_numeric(n) {
return(n ! = =' ' && !isNaN(parseFloat(n)) && isFinite(n));
}
Object.keys(styles).forEach(function(prop) {
var unit = ' ';
if (['width'.'height'.'top'.'right'.'bottom'.'left'].indexOf(prop) ! == -1 && is_numeric(styles[prop])) { unit ='px';
}
element.style[prop] = styles[prop] + unit;
});
}
setStyle(document.getElementById("myDiv"),{ position: 'absolute', top: 0 })
Copy the code
Element.style returns only inline styles, not all styles for that Element. Styles set through the stylesheet, or inherited from the parent element, are not available through this property. The full style of the element is obtained via window.getComputedStyle().
4.1 CSSStyleDeclaration
Object properties and methods
cssText
: Allows you to access CSS code in the Style feature, readable and writable.length
: The number of CSS attributes applied to an element.parentRule
: Represents the CSSRule object of CSS information.getPropertyPriority(propertyName)
: : If the given attribute is used! Important, return “important”; Otherwise, an empty string is returned.getPropertyValue(propertyName)
: : Returns the string value of the given attribute.item(index)
: Returns the name of the CSS property at a given location.removeProperty(propertyName)
: Removes the given attribute from the style.setProperty(propertyName,value,priority)
: Sets the given attribute to the corresponding value with a priority flag (“important” or an empty string).
cssText
Break down
The CSS code in the Style feature is accessed through the cssText property. In read mode, cssText returns the browser’s internal representation of the CSS code in the Style feature. In write mode, the value assigned to cssText overrides the value of the entire style feature; That is, the style information previously specified by the style feature is lost. For example, if you set a border on an element with the style feature and then override cssText with no border, the border on the element will be erased.
<div id="demo" style="border:5px solid red;">容器</div>
var myDiv = document.getElementById("myDiv");
myDiv.style.cssText = "background-color: green";
console.log(myDiv.style.cssText) //background-color: green;
Copy the code
Setting cssText is the quickest way to apply multiple changes to an element, because you can apply them all at once.
length
Properties,item()
Method,getPropertyValue()
Method,removeProperty()
methods
The Length attribute is designed to work with the item() method to iterate over CSS attributes defined in the element. When using length and item(), the style object is really a collection:
<div id="demo" style="width:100px; font-size:22px;"> container </div> const myDiv = document.getelementById ('demo');
for(leti = 0; i < myDiv.style.length; Mydiv.style.item (I) console.log(mydiv.style [I]) //width font size}Copy the code
You can get the CSS property name (“background-color”, not “backgroundColor”) using either the square bracket syntax or the item() method. You can then use the acquired property name in getPropertyValue() to further obtain the value of the property.
<div id="demo" style="width:100px; font-size:22px;"> container </div> const myDiv = document.getelementById ('demo');
var prop, value, i, len;
for (i=0, len= myDiv.style.length; i < len; i++){
prop = myDiv.style[i];
value = myDiv.style.getPropertyValue(prop);
console.log(prop + ':' + value); //width:100px font-size:22px
}
Copy the code
To remove a CSS property from an element’s style, use the removeProperty() method. Using this method to remove a property means that the default style (cascading from other stylesheets) will be applied to the property. For example, to remove the font-size property set by the style feature:
<div id="demo" style="width:100px; font-size:22px;"> container </div> const myDiv = document.getelementById ('demo');
myDiv.style.removeProperty("font-size");
Copy the code
You can apply a default value to an element by simply removing the corresponding attribute.
4.2 getComputedStyle()
Get the style of the calculation
While the Style object can provide style information for any element that supports the Style feature, it does not contain style information that is layered from other style sheets and affects the current element.
The dom2-level style enhances document.DefaultView to provide the getComputedStyle() method. This method takes two arguments: the element to get the computed style and a pseudo-element string (for example, “:after”). If no pseudo-element information is required, the second argument can be null. The getComputedStyle() method returns a live CSSStyleDeclaration object that updates itself automatically when the element’s style changes. This contains all the computed styles for the current element.
Window.getcomputedstyle () can also get the element’s CSSStyleDeclaration object. Document. The defaultView. GetComputedStyle (), and the window. The getComputedStyle () the difference, please refer to: MDN this article.
The following code gets the element style from window.getComputedStyle() :
<style type="text/css">
.demo {
background-color: blue;
width: 100px;
height: 200px;
}
</style>
<div id="demo" style="background-color: red; border: 5px solid black;"> container </div> <script> const myDemo = document.getelementById ('demo');
const computedStyle = window.getComputedStyle(myDemo,null);
console.log(computedStyle.backgroundColor); //rgb(255, 0, 0)
console.log(computedStyle.width); //100px
console.log(computedStyle.height); //200px
console.log(computedStyle.border); //5px solid rgb(0, 0, 0)
</script>
Copy the code
The background color printed above is not “blue” because the style is already overwritten in its own style property.
The border property may or may not return the actual border rule in the stylesheet. Because setting this property (the composite property) actually involves many other properties. When you set a border, you actually set the border width, color, style attributes for the four edges (border-left-width, border-top-color, border-bottom-style, etc.). . Because of this, even if computedStyle border will not return values in all browsers, but specific to computedStyle. BorderLeftWidth will return a value.
IE does not support the getComputedStyle() method, but it has a similar concept. In IE, every element that has a style attribute also has a currentStyle attribute. This property is an instance of CSSStyleDeclaration. Here is an example of a compatibility pattern:
function getStyles(elem) {
window.getComputedStyle ? window.getComputedStyle(elem,null) : elem.currentStyle;
}
var myDemo = document.getElementById('demo');
var computedStyle = getStyles(myDemo)
Copy the code
All computed styles are read-only. You cannot modify CSS properties in a computed style object.
Part five: Examples
5.1 Setting the Style
const ieVersion = Number(document.documentMode); /** * change :-_, etc., to camelCase, such as foo-bar to fooBar * @param name to process string * @returns {*} processed string */ const camelCase =function(name) {
returnname.replace(/([\:\-\_]+(.) )/g,function(_, separator, letter, offset) {// The beginning is not uppercase, the rest is uppercasereturn offset ? letter.toUpperCase() : letter;
}).replace(/^moz([A-Z])/, 'Moz$1'); // special processing for moz}; /** * Set element style * @param Element to set element * @param styleName to set style * @param value to set value */function setStyle(element, styleName, value) {
if(! element || ! styleName)return; // If it is an object, set it one by oneif (typeof styleName === 'object') {
for (var prop in styleName) {
if (styleName.hasOwnProperty(prop)) {
setStyle(element, prop, styleName[prop]); }}}else{ styleName = camelCase(styleName); // Opacity special handlingif (styleName === 'opacity' && ieVersion < 9) {
element.style.filter = isNaN(value) ? ' ' : 'alpha(opacity=' + value * 100 + ') ';
} else{ element.style[styleName] = value; }}};Copy the code
5.2 Getting the Style
var ieVersion = Number(document.documentMode); /** * change :-_, etc., to camelCase, such as foo-bar to fooBar * @param name to process string * @returns {*} processed string */ const camelCase =function(name) {
returnname.replace(/([\:\-\_]+(.) )/g,function(_, separator, letter, offset) {// The beginning is not uppercase, the rest is uppercasereturn offset ? letter.toUpperCase() : letter;
}).replace(/^moz([A-Z])/, 'Moz$1'); // special processing for moz}; /** * get the style, which is handled in IE9 and two other ways * @type{Function} * @param element to get the style element * @param styleName to get the styleName */ var getStyle = ieVersion < 9?function(element, styleName) {
if(! element || ! styleName)returnnull; // change the styleName to camelCase styleName = camelCase(styleName); //floatSpecial handlingif (styleName === 'float') {
styleName = 'styleFloat'; // Opacity switch (styleName) {case 'opacity':
try {
return element.filters.item('alpha').opacity / 100;
} catch (e) {
return 1.0;
}
default:
return (element.style[styleName] || element.currentStyle ? element.currentStyle[styleName] : null);
}
} catch (e) {
returnelement.style[styleName]; }} :function(element, styleName) {
if(! element || ! styleName)return null;
styleName = camelCase(styleName);
if (styleName === 'float') {
styleName = 'cssFloat';
}
try {
var computed = document.defaultView.getComputedStyle(element, ' ');
return element.style[styleName] || computed ? computed[styleName] : null;
} catch (e) {
returnelement.style[styleName]; }};Copy the code
5.3 Add and remove Class styles
Returns {Boolean} */ returns {Boolean} */ returns {Boolean} */function hasClass(el, cls) {
if(! el || ! cls)return false;
if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.');
if (el.classList) {
return el.classList.contains(cls);
} else {
return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > 1; }}; /** * Add some classes to the element * @param el to process * @param CLS to add classes */function addClass(el, cls) {
if(! el)return;
var curClass = el.className;
var classes = (cls || ' ').split(' ');
for (var i = 0, j = classes.length; i < j; i++) {
var clsName = classes[i];
if(! clsName)continue;
if (el.classList) {
el.classList.add(clsName);
} else if(! hasClass(el, clsName)) { curClass +=' '+ clsName; }}if(! el.classList) { el.className = curClass; }}; /** * Remove some classes from the element * @param el to handle the element * @param CLS to remove the class */function removeClass(el, cls) {
if(! el || ! cls)return;
var classes = cls.split(' ');
var curClass = ' ' + el.className + ' ';
for (var i = 0, j = classes.length; i < j; i++) {
var clsName = classes[i];
if(! clsName)continue;
if (el.classList) {
el.classList.remove(clsName);
} else if (hasClass(el, clsName)) {
curClass = curClass.replace(' ' + clsName + ' '.' '); }}if (!el.classList) {
el.className = trim(curClass);
}
};
Copy the code
Refer to the link
JavaScript Advanced Programming (version 3)
JavaScript DOM advanced programming
Familiar with the getComputedStyle method for obtaining element CSS values
CSS Object Model
Stylesheets can be constructed
Familiar with the getComputedStyle method for obtaining element CSS values
CSS operation
Github.com/ElemeFE/ele…