Change pseudo-selection: after in javascript

I defined css as

.slidingTag li:after { content: ''; z-index: 3; height: 6px; } 

I want to dynamically change the height attribute from JS. I can get the property using

 window.getComputedStyle(document.querySelector('.slidingTag'), 'li:after').getPropertyValue('height') 

But I do not know how to change the height attribute. I tried using setProperty , but it seems that there is no such function for pseudo-classes. Any ideas let me know.

+6
source share
3 answers

If this style comes from a CSS file, you will have to look for it in document.styleSheets , which will be messy.

If you are open to dynamically creating a <style> element containing this CSS, you can change it programmatically.

 var slidingTagLiAfterStyle = document.createElement("style"); slidingTagLiAfterStyle.innerHTML = ".slidingTag li:after { content: ''; z-index: 3; height: 6px; }"; document.head.appendChild(slidingTagLiAfterStyle); ... slidingTagLiAfterStyle.innerHTML = slidingTagLiAfterStyle.innerHTML.replace(/height: [0-9]+px/, "height: 12px"); // or whatever you want to set it to 
+6
source

Pseudo-elements like: before and: after are handled by CSS, not the DOM . Because of this, you need to take a different approach.

What you can do is find the CSS rule responsible for this pseudo-element and modify it. . You do this using CSSOM, which is a completely different API, although you first access it from the DOM.

Unlike the DOM, CSS rules do not have identifiers or class names that can be found clean and quick, so we need to search the list of stylesheets and style rules. This can be expensive, so if it can only be searched once, I highly recommend doing it . Here is a quick and dirty way to do this:

 function getRuleWithSelector(selector) { var numSheets = document.styleSheets.length, numRules, sheetIndex, ruleIndex; // Search through the style sheets. for (sheetIndex = 0; sheetIndex < numSheets; sheetIndex += 1) { numRules = document.styleSheets[sheetIndex].cssRules.length; for (ruleIndex = 0; ruleIndex < numRules; ruleIndex += 1) { if (document.styleSheets[sheetIndex].cssRules[ruleIndex].selectorText === selector) { return document.styleSheets[sheetIndex].cssRules[ruleIndex]; } } } // If we get this far, then the rule doesn't exist. // So the return value is undefined. } var afterSlidingTagRule = getRuleWithSelector('.slidingTag li::after'); console.debug(afterSlidingTagRule); window.addEventListener('DOMContentLoaded', function() { afterSlidingTagRule.style.fontSize = "10px"; }, false); 
 .slidingTag { color: blue; } .slidingTag li { color: green; } .slidingTag li:after { content: "World"; font-size: 32px; } 
 <ul class="slidingTag"> <li class="selected">Hello</li> <li>World</li> </ul> 

Once you get the rule you want, the rest is very similar to working with getComputedStyle () or with the DOM style attribute . The snippet above does this in the DOMContentLoaded event handler, but you should be able to do this at any time once things are loaded.

There are a few caveats to consider with this approach:

  • When you change the CSS rule, that change is reflected in every element that the rule selects. If you have a rule that affects many elements, and you need to change the way you display all of these elements, fine. If you have a rule that affects many elements, but you only need to change the appearance of one of these elements, this is not so good.
  • Viewing the CSSOM of your selector text may not match what you wrote . This happens exactly in this example, because your selector must read .slidingTag li::after (note the extra colon). The browser fixes this when it parses your CSS, and this is what CSSOM knows.
  • Just because the rule says that something does not mean that the element will be displayed in this way . Anything that can override the styles of specific CSS rules, more specific rules elsewhere in the collection, declarations !important , etc., can also override your changes.
  • This is not a replacement for getComputedStyle() . This follows from the above: if something changes the presentation of an element, it does not affect the basic CSS rules. In any case, this is the opposite of getComputedStyle() : instead of getting what the element is currently displaying, it sets which specific elements should be displayed (prohibition of unforeseen circumstances).
+4
source

You can add an additional class to an element that has another property in :after , for example:

first you have this:

HTML:

 <div class="slidingTag"> <li>lorem ipsum</li> </div> 


CSS

 .slidingTag li:after { content: ''; z-index: 3; height: 6px; } 

then you got the following:

A new class that will override the height property:

 .slidingTag-modifier li:after { content: ''; z-index: 3; height: 10px !important; } 

final HTML:

 <div class="slidingTag slidingTag-modifier"> <li>lorem ipsum</li> </div> 

To do this using javascript:

 var element = document.querySelector('.slidingTag'); //use this instruction wherever you want to add the new class that will override the property element.classList.add('slidingTag-modifier'); //works only on recent browsers 

Hooray!

+1
source

Source: https://habr.com/ru/post/984243/


All Articles