【问题标题】:Modifying of css by document.styleSheets通过 document.styleSheets 修改 css
【发布时间】:2020-05-28 15:59:13
【问题描述】:

我尝试通过更改来修改 CSS:

document.styleSheets[0].cssRules[0].style.fontSize = '1rem';

它在 PC 上完美运行,但使用移动浏览器(至少 chrome 和 mozilla)触发此脚本无效。

我做错了什么?如果由于某种原因,这种修改 CSS 的方式不受全球支持,我该如何修改 CSS 不同的方式?

编辑:我想更改所有现有和所有未来动态添加的具有确切类的对象的样式。所以el.style.fontSize 不是很好的选择。

【问题讨论】:

  • 使用CSS变量会更好
  • 根据 mdn,document.styleSheets 是一个实验性功能,但兼容广泛。 CSSStylesheet Api 可能有您需要的答案。从该页面:“要在 cssRules 中添加或删除项目,请使用 CSSStyleSheetinsertRule()deleteRule() 方法。”
  • 谢谢,但遗憾的是没有 modifyRule() 方法 :) 我想修改现有规则,而不是插入/更改规则/类。

标签: javascript css mobile-chrome


【解决方案1】:

直接修改 styleSheets 可能很棘手。

我更喜欢在文档中添加一个新的style 元素,并将修改后的 CSS 放在那里。由于它是文档中的最后一个样式元素,因此它将覆盖任何具有匹配选择器的早期 CSS 规则。

例如,这会将正文的字体大小设置为 1rem:

let style = document.createElement('style');
style.innerHTML = 'body { font-size: 1rem; }';
document.head.appendChild(style);

【讨论】:

  • 不是很优雅,但它似乎是今天更好的稳定方式。谢谢。
  • @YuriyO。这肯定比破解未记录的数据结构更优雅。
  • 哈哈。我同意:)
  • «由于它是文档中的最后一个样式元素,它将覆盖早期的 CSS 规则» ...具有相同的特性 :o)
  • @agrm 更新了答案:“它将覆盖任何具有匹配选择器的早期 CSS 规则”
【解决方案2】:

当我上次处理这个操作时,许多浏览器都不太支持 CSSOM(我认为这还没有改变)。

如果您想将样式应用于单个元素,请直接在元素上进行。

如果您想在运行时生成 css 规则,您还可以考虑将样式标签放入文档中:

var style = document.createElement('style');

// set style properties
// append the style tag to the head or somewhere in the body

head.appendChild(style);

【讨论】:

  • 运行时的 Css 规则——这正是我所需要的。不是很优雅的解决方案,但它似乎是迄今为止更好的稳定方法。谢谢。
【解决方案3】:

来自MDN docs(约DocumentOrShadowRoot.styleSheets):

这是一项实验性技术。

在生产中使用它之前,请仔细检查Browser compatibility table

预计未来的行为会发生变化。

因此,我建议不要使用该方法。

但是,我无法更详细地解释您为什么会看到您所描述的问题,因为大多数浏览器都应该在链接的兼容性表中支持此功能。


现在回答你的下一个问题:

如何以不同的方式修改 CSS?

我总是先通过 DOM 获取元素,然后直接将样式应用于元素。例如:

var myEl = document.getElementById("myId");

那么你可以这样做:

myEl.style.fontSize = "1rem";


如果您不想通过其id 属性来定位元素,您可以使用其他几种方法:

  1. getElementsByClassName() – 采用类名的字符串值,例如。 "myClass"
  2. getElementsByTagName() – 采用标签名称的字符串值,例如。 "body", "div"
  3. querySelector() – 获取 CSS 选择器的字符串值,例如。 "div.myClass p"

但是,它们不会像id 选择器那样返回单个元素。例如,要获取特定类的第一个元素:

var myEl = document.getElementsByClassName("myClass")[0];

第四个是:

var myEl = document.getElementsByClassName("myClass")[3];

【讨论】:

  • 谢谢。但我想更改所有现有和所有未来动态添加的对象的样式,具有精确的类。
【解决方案4】:

使用 css 变量您将拥有更多控制权,您可以在下面找到一个小演示来说明我的观点

let root = document.documentElement;

document
  .querySelector('button')
  .addEventListener('click', () => {
    let currentVal = Number(getComputedStyle(root).getPropertyValue('--defaultFontSize').replace('px', ''));
    root.style.setProperty('--defaultFontSize', `${currentVal + 5}px`);
  });
:root {
  --defaultFontSize: 20px;
}

.text {
  font-size: var(--defaultFontSize);
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <p class="text">Some text</p>
  
  <button>Increse font size</button>
</body>
</html>

【讨论】:

    【解决方案5】:

    如果你有任何你想修改的类名或id,你可以使用jquery css()方法。

    例如:$("#whateverID").css('font-size', '1rem');

    【讨论】:

    • 我不确定添加一个库 OP 没有说他们正在使用是个好主意。
    • 这是一个使用建议。 OP 是否需要指定他正在使用某个库?
    • 完全是@SvenWritesCode .. 我用“你可以使用jquery css() 方法”我没有强迫他这样做;)
    • 谢谢。我想使用纯js。此外,正如我上面提到的,我想更改所有现有和所有未来动态添加的具有确切类的对象的样式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2016-07-14
    • 1970-01-01
    • 2017-12-13
    • 2018-04-28
    相关资源
    最近更新 更多