有没有办法使用规则名称指向 document.styleSheets[].cssRules[]?



我想使用Javascript更改特定的类属性值,但通过类名本身而不是任何整数作为指针(cssRules[i](或循环所有类以查找匹配的"selectorText"值。

这是为了更改页面中可读的屏幕语言。

<style id="languages" class="languages" title="languages">
<!--
/* ... more styles ... */
.lang-ita { display : none; }
.lang-eng { display : none; }
/* ... more styles ... */
-->
</style>
<script language="javascript">
<!--
function fxSwitchLanguage(i)
{
/* ... more code ... */
document.getElementById('languages').sheet.cssRules[i].style.setProperty('display','block');
/* ... more code ... */
}
-->
</script>
<button onClick="fxSwitchLanguage(0);">ITA</button>
<button onClick="fxSwitchLanguage(1);">ENG</button>
<br>
<div class="lang-ita">CIAO!</div>
<div class="lang-eng">HELLO!</div>

当然,我将以前的语言"display"设置为"none",然后再仅显示新选择的语言。

我想要".cssRules['.lang-eng']"而不是".cssRules[i]"。

由于此文档是共享的并且可能会被其他人更改,因此出于明显的稳定性原因,我确实更喜欢使用其名称而不是任何硬编码整数来指向类,此外,我不想使用"for"循环来测试每个编写类的"selectorText"属性(可以很容易地是数千个(。

我不介意任何浏览器的差异(.cssRules或.rules(。

我只想知道是否有可能以我想要的方式拥有它。

不,没有 CSSOM API 可以通过其选择器字符串获取规则(或规则列表(。迭代它们以找到一个是唯一的方法。当然,您不会在每次调用fxSwitchLanguage函数时执行此操作,但在函数之外,仅在加载脚本时执行此操作一次。然后,只需将对相关规则的引用存储在几个常量或数据结构中即可。

但是由于你的目标是通过JavaScript操纵规则,我会走得更远,并使用javascript创建它们。这样,您可以轻松地存储对它们的引用,而无需迭代。

const {sheet} = document.getElementById('languages');
const rules = new Map(['eng', 'ita', 'esp'].map(lang => {
const rule = sheet.cssRules[sheet.insertRule(`.lang-${lang} {
display: none;
}`)]; // yes, it's weird, `insertRule` returns an index
return [lang, rule];
}));
let active = null;
function fxSwitchLanguage(l) {
if (active) rules.get(active).style.display = 'none';
rules.get(l).style.display = 'block';
active = l; 
} // or build a toggle or whatever
<style id="languages">
</style>
<button onClick="fxSwitchLanguage('ita');">ITA</button>
<button onClick="fxSwitchLanguage('eng');">ENG</button>
<button onClick="fxSwitchLanguage('esp');">ESP</button>
<br>
<div class="lang-ita">CIAO!</div>
<div class="lang-eng">HELLO!</div>
<div class="lang-esp">HOLA!</div>

从评论中可以看出:

function fxSwitchLanguage(varlang) {
//* test if already created and remove it before update*/
if (document.contains(document.getElementById("langSetting"))) {
document.getElementById("langSetting").remove();
}
//* update language chosen*/
var newStyle = document.createElement("style");
newStyle.setAttribute("id", "langSetting"); //* put a mark on it */
var addContent = ".lang-" + varlang + "{display:block;}";
newStyle.appendChild(document.createTextNode(addContent));
var head = document.getElementsByTagName("head")[0];
head.appendChild(newStyle);
}
[class^='lang'] {display:none;}
<button onClick="fxSwitchLanguage('ita');">ITA</button>
<button onClick="fxSwitchLanguage('eng');">ENG</button>
<hr>
<p class="lang-ita">CIAO!</p>
<div class="lang-eng">HELLO!</div>