能否使用JavaScript更改CSS样式表?
我不是在讨论以下内容:
document.getElementById('id').style._____='.....';
我指的是修改:
#id {
param: value;
}
除了做一些“肮脏的事情”(我们还没有尝试过),比如在头部创建一个新对象,在其中innerHTML一个样式标签等等。虽然如此,即使它起作用,也会带来一些问题,因为样式块已经在其他地方定义了,而且我不确定浏览器何时/是否会解析动态创建的样式块。
能否使用JavaScript更改CSS样式表?
我不是在讨论以下内容:
document.getElementById('id').style._____='.....';
我指的是修改:
#id {
param: value;
}
除了做一些“肮脏的事情”(我们还没有尝试过),比如在头部创建一个新对象,在其中innerHTML一个样式标签等等。虽然如此,即使它起作用,也会带来一些问题,因为样式块已经在其他地方定义了,而且我不确定浏览器何时/是否会解析动态创建的样式块。
是的,你可以;每个浏览器都支持这一点,包括IE9+。
insertRule()
方法允许动态添加样式规则到样式表中。
使用 deleteRule()
方法,可以从样式表中移除现有的规则。
样式表中的规则可以通过样式表的 cssRules
属性进行访问。
我们可以使用 .insertRule
和 .cssRules
的组合方式,以便能够在 IE9 上实现这一点:
function changeStylesheetRule(stylesheet, selector, property, value) {
// Make the strings lowercase
selector = selector.toLowerCase();
property = property.toLowerCase();
value = value.toLowerCase();
// Change it if it exists
for(var i = 0; i < stylesheet.cssRules.length; i++) {
var rule = stylesheet.cssRules[i];
if(rule.selectorText === selector) {
rule.style[property] = value;
return;
}
}
// Add it if it does not
stylesheet.insertRule(selector + " { " + property + ": " + value + "; }", 0);
}
// Used like so:
changeStylesheetRule(s, "body", "color", "rebeccapurple");
s.deleteRule(i)
以及删除“return”语句来完成。 - u01jmg3backgroundPosition
之类的属性将无法工作。为了在insertRule()
中使用,这也需要转换为其连字符等效形式(background-position
)。 - u01jmg3此方法的一些优点:
!important
属性。用法:
adjustCSSRules('#myDiv', 'width: 300px !important');
方法:
function adjustCSSRules(selector, props, sheets){
// get stylesheet(s)
if (!sheets) sheets = [...document.styleSheets];
else if (sheets.sup){ // sheets is a string
let absoluteURL = new URL(sheets, document.baseURI).href;
sheets = [...document.styleSheets].filter(i => i.href == absoluteURL);
}
else sheets = [sheets]; // sheets is a stylesheet
// CSS (& HTML) reduce spaces in selector to one.
selector = selector.replace(/\s+/g, ' ');
const findRule = s => [...s.cssRules].reverse().find(i => i.selectorText == selector)
let rule = sheets.map(findRule).filter(i=>i).pop()
const propsArr = props.sup
? props.split(/\s*;\s*/).map(i => i.split(/\s*:\s*/)) // from string
: Object.entries(props); // from Object
if (rule) for (let [prop, val] of propsArr){
// rule.style[prop] = val; is against the spec, and does not support !important.
rule.style.setProperty(prop, ...val.split(/ *!(?=important)/));
}
else {
sheet = sheets.pop();
if (!props.sup) props = propsArr.reduce((str, [k, v]) => `${str}; ${k}: ${v}`, '');
sheet.insertRule(`${selector} { ${props} }`, sheet.cssRules.length);
}
}
该方法需要三个参数:
.myClass #myDiv
将匹配 .myClass #myDiv
){ border: "solid 3px green", color: "white" }
'border: solid 3px green; color: white'
document.styleSheets[1]
- 指向样式表的引用其他示例:
adjustCSSRules('#myDiv', {width: '30px'}); // all stylesheets
adjustCSSRules('#myDiv', 'width: 30px', 'style.css'); // style.css only
adjustCSSRules('#myDiv .myClass', 'width: 30px', document.styleSheets[0]); // only first stylesheet
当我想要通过编程方式为对象添加一堆样式时,我发现将一个类编程地添加到对象中更容易(这个类在你的CSS中有与之相关联的样式)。你可以在你的CSS中控制优先级顺序,以便来自新类的新样式可以覆盖以前的样式。这通常比直接修改样式表要容易得多,并且可以完美地跨浏览器工作。
更改样式规则中的属性
function change_css_style (titulo,selector,propiedad,valor) {
let i=0;
while (i<document.styleSheets.length) {
if (document.styleSheets[i].title==titulo) {
let y=0;
while (y<document.styleSheets[i].cssRules.length) {
if (document.styleSheets[i].cssRules[y].selectorText==selector) {
document.styleSheets[i].cssRules[y].style[propiedad] = valor;
y = document.styleSheets[i].cssRules.length;
}
y++;
}
i=document.styleSheets.length;
}
i++;
}
}
演示
<style title="chat_inicio">
.contenido .mensajes {
width: 100px;
height: 300px;
}
</style>
<script>
cambiar_css_style ('chat_inicio','.contenido .mensajes','width','475px');
</script>
.style.cssText属性可用,尝试使用以下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
*{
margin: 0%;
padding: 0%;
}
html {
--theme-orange: orangered;
--theme-blue: rgb(67, 67, 197);
--theme-green: darkgreen;
--theme-black: black;
--theme-color: var(--theme-orange);
}
body {
font-family: 'Roboto', sans-serif;
background-color: rgb(251, 251, 251);
}
.nav-bar ul {
display: flex;
width: 100%;
background-color: var(--theme-color);
flex-wrap: wrap;
flex-direction: row;
align-items: center;
width: 100%;
}
.nav-bar ul a {
text-decoration: none;
margin: 15px 10px;
}
.nav-bar .theme {
background-color: white;
display: flex;
height: fit-content;
margin-left: auto;
margin-right: 20px;
border-radius: 10px;
}
.nav-bar .theme .box {
width: 20px;
height: 20px;
border: 1px solid black;
cursor: pointer;
}
.nav-bar .theme .orange {
background-color: var(--theme-orange);
}
.nav-bar .theme .blue {
background-color: var(--theme-blue);
}
.nav-bar .theme .green {
background-color: var(--theme-green);
}
.nav-bar .theme .black {
background-color: var(--theme-black);
}
.nav-bar ul li {
color: white;
font-weight: 500;
list-style: none;
padding: 10px 30px;
background-color: var(--theme-color);
transition: 0.2s;
}
.nav-bar ul li:hover {
box-shadow: inset 10px 10px 10px -12px;
scale: 0.95;
}
</style>
<body>
<div class="nav-bar">
<ul>
<a href=""><li>Home</li></a>
<a href=""><li>Page 1</li></a>
<a href=""><li>Page 2</li></a>
<a href=""><li>About Us</li></a>
<a href=""><li>Contact Us</li></a>
<div class="theme">
<a><div class="box orange" id="orange"></div></a>
<a><div class="box blue" id="blue"></div></a>
<a><div class="box green" id="green"></div></a>
<a><div class="box black" id="black"></div></a>
</div>
</ul>
</div>
<script>
function colorChange(color) {
const htmlTag = document.getElementsByTagName("*")[0];
htmlTag.style.cssText = `--theme-orange: orangered;
--theme-blue: rgb(67, 67, 197);
--theme-green: darkgreen;
--theme-black: black;
--theme-color: var(--theme-${color});`;
}
function addEventListenerForBox() {
allBox = document.querySelectorAll('.box');
allBox.forEach(box => {
box.addEventListener('click', (event) => {
colorChange(event.target.id);
});
});
}
document.addEventListener('DOMContentLoaded', addEventListenerForBox);
</script>
</body>
</html>
#casesDndDropdown {
background: #FFFFFF;
border: 4px
}
您可以通过在标签内的<style>
标签中定义来覆盖#casesDndDropdown或任何CSS类,
jQuery
$('<style>#id{background: #428bca;border: 0px}</style>').appendTo('body');
几年前我在w3schools: HTML style Tag中读到,<style>
元素支持HTML全局属性和HTML事件属性。
上述意味着,在href
、rel
和target
之外,任何样式表都可以通过切换其disabled
属性来禁用。我不得不深入挖掘以验证此规范是何时和如何实现的,并找到了一份旧的(2000年11月)W3C文档,其中已经提到了对样式表的disabled
属性的支持。
tl;dr
<style disabled>
这样将disabled
直接放在样式定义中是无效的。disabled
属性false/true会禁用/启用整个引用的<style>...</style>
块,不管此块位于文档中的何处。您只需要一个样式表元素的引用以及几个Javascript一行代码:
function disabledToggle(e) { e.disabled = !e.disabled }
function disabledOff (e) { e.disabled = false }
function disabledOn (e) { e.disabled = true }
知道了
media
属性规范。<link>
元素还支持上述提到的HTML全局属性和HTML事件属性。本质上,一直以来都可以用一个简单的方法摧毁样式表。
一个简单的概念证明:
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Alternate font, activated in default <style>, but can be toggled on/off -->
<link id="lnk-poppins" href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
<!-- Default styling, considered 'always active' -->
<style>
* { box-sizing: border-box }
body { font-family: Poppins, sans-serif }
.square {
margin: 5rem auto;
width : 50vmin; aspect-ratio: 1;
background-color: CornflowerBlue;
}
</style>
<!-- Media controlled style, only active on small devices -->
<style media="all and (max-width: 640px)">
body {
margin: 0; padding: 1rem;
width: 100%; min-height: 100vh;
background-color: hsl(90,100%,50%,.3);
}
</style>
<!-- Alternative styles: last in, first serve, so order matters -->
<style id="stl-red" >.square { background-color: Red }</style>
<style id="stl-green">.square { background-color: Green }</style>
<style id="stl-blue" >.square { background-color: Blue }</style>
<!-- Default style, but can be toggled: overrides all above when enabled -->
<style id="stl-default" >.square { background-color: Black }</style>
</head>
<body>
<fieldset>
<legend> Style Toggles </legend>
<p>Colors:</p>
<label for="default">
<input id="default" class="radio" type="radio" name="group" checked
oninput="disabledOff(defa);">
Default
</label>
<label for="red">
<input id="red" class="radio" type="radio" name="group"
oninput="disabledOff(red);disabledOn(defa);disabledOn(blue);disabledOn(green);">
Red
</label>
<label for="green">
<input id="green" class="radio" type="radio" name="group"
oninput="disabledOff(green);disabledOn(defa);disabledOn(blue);">
Green
</label>
<label for="blue">
<input id="blue" class="radio" type="radio" name="group"
oninput="disabledOff(blue);disabledOn(defa);">
Blue
</label>
<p>Font:</p>
<label for="poppins">
<input id="poppins" type="checkbox" oninput="disabledToggle(popp);" checked>
Poppins
</label>
<br><br>
<span>Old W3C Reference: <a target="_blank" href="https://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-StyleSheet-disabled">Attributes: <b>disabled</b> of type boolean</a></span>
</fieldset>
<div class="square"></div>
<script>
const red = document.getElementById('stl-red');
const green = document.getElementById('stl-green');
const blue = document.getElementById('stl-blue');
const defa = document.getElementById('stl-default');
const popp = document.getElementById('lnk-poppins');
function disabledToggle(e) { e.disabled = !e.disabled }
function disabledOff (e) { e.disabled = false }
function disabledOn (e) { e.disabled = true }
</script>
</body>
</html>
<style>
元素,然后将其附加到<head>
元素的末尾。我猜它会在被附加时立即应用,就像链接到样式表的<link>
一样。这可能比尝试编辑样式表本身更可靠。 - Paul D. Waite