简体   繁体   中英

Is there a way to point to document.styleSheets[].cssRules[] using a rule name?

I want to change a specific class-property-value using Javascript, but by the class-name itself and not with any integer as a pointer (cssRules[i]) or looping all classes to find the matching "selectorText" value.

This is for changing the readable on-screen language within the page.

<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>

Of course I set the previous language "display" to "none" before showing only the new selected one.

I would like to have ".cssRules['.lang-eng']" instead of ".cssRules[i]".

Since this document is shared and may be changed by someone else, I really DO prefer to point the class using its name and not any hard-coded integer for obvious stability reasons, moreover I do not want to use a "for" cycle to test the "selectorText" property of each written class (can be easily thousands).

I don't mind any Browsers differences (.cssRules or .rules).

I just want to know if it is possible to have it in the way I'd prefer to.

from comment here is the idea :

 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> 

No, there is no CSSOM API to get a rule (or list of rules) by its selector string. Iterating them to find one is the only way. Of course you wouldn't do this in the fxSwitchLanguage function, everytime it is called, but outside of it, only once when the script is loaded. Then just store references to the relevant rules in a few constants, or a data structure.

But since your goal is to manipulate the rules by JavaScript, I'd go even further and also create them using javascript. That way, you can easily store a reference to them without iteration.

 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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM