Ställa in CSS pseudo-klassregler från JavaScript
Jag letar efter ett sätt att ändra CSS-regler för pseudo-klass-selektorer (såsom :link, :hover, etc.) från JavaScript.
Så en motsvarighet till CSS-koden: a:hover { color: red } i JS.
Jag kunde inte hitta svaret någon annanstans; om någon vet att detta är något som webbläsare inte stöder, skulle det också vara ett användbart resultat.
Svar #1
Du kan inte styla en pseudo-klass på ett enskilt element ensam, på samma sätt som du inte kan ha en pseudo-klass i en inline style="..."-attribut (eftersom det inte finns någon selektor).
Du kan göra det genom att ändra stilmallen, till exempel genom att lägga till regeln:
#elid:hover { background: red; }
förutsatt att varje element du vill påverka har ett unikt ID för att det ska kunna väljas.
I teorin är dokumentet du vill ha http://www.w3.org/TR/DOM-Level-2-Style/Overview.html vilket betyder att du kan (givet ett förhandsbefintligt inbäddat eller länkat stilmall) använda syntax som:
document.styleSheets[0].insertRule('#elid:hover { background-color: red; }', 0);
document.styleSheets[0].cssRules[0].style.backgroundColor= 'red';
IE kräver förstås sin egen syntax:
document.styleSheets[0].addRule('#elid:hover', 'background-color: red', 0);
document.styleSheets[0].rules[0].style.backgroundColor= 'red';
Äldre och mindre webbläsare stöder troligen inte någon av syntaxerna. Dynamisk ändring av stilmallar görs sällan eftersom det är ganska irriterande att få rätt, sällan behövs och historiskt sett problematiskt.
Svar #2
Jag slängde ihop ett litet bibliotek för detta eftersom jag faktiskt tycker att det finns giltiga användningsfall för att manipulera stilmallar i JS. Anledningarna är:
- Ställer in stilar som måste beräknas eller hämtas - till exempel att ställa in användarens föredragna teckenstorlek från en cookie.
- Ställa in beteendemässiga (inte estetiska) stilar, särskilt för UI-widget-/pluginutvecklare. Flikar, karuseller osv. kräver ofta något grundläggande CSS bara för att fungera - bör inte kräva ett stylesheet för kärnfunktionen.
- Bättre än inline-stilar eftersom CSS-regler gäller för alla nuvarande och framtida element och inte rör till HTML när man tittar i Firebug/Developer Tools.
Svar #3
Placera bara CSS:en i en mallsträng.
const cssTemplateString = `.foo:[psuedoSelector]{prop: value}`;
Skapa sedan ett style-element och placera strängen i style-taggen och bifoga det till dokumentet.
const styleTag = document.createElement("style");
styleTag.innerHTML = cssTemplateString;
document.head.insertAdjacentElement('beforeend', styleTag);
Specificitet tar hand om resten. Sedan kan du ta bort och lägga till stil-taggar dynamiskt. Detta är ett enkelt alternativ till bibliotek och att mixtra med stylesheet-arrayen i DOM. Glad kodning!
Svar #4
En funktion för att hantera saker som skiljer sig mellan webbläsare:
addCssRule = function(/* string */ selector, /* string */ rule) {
if (document.styleSheets) {
if (!document.styleSheets.length) {
var head = document.getElementsByTagName('head')[0];
head.appendChild(bc.createEl('style'));
}
var i = document.styleSheets.length-1;
var ss = document.styleSheets[i];
var l=0;
if (ss.cssRules) {
l = ss.cssRules.length;
} else if (ss.rules) {
// IE
l = ss.rules.length;
}
if (ss.insertRule) {
ss.insertRule(selector + ' {' + rule + '}', l);
} else if (ss.addRule) {
// IE
ss.addRule(selector, rule, l);
}
}
};
