javascript 修改伪选择:在javascript中之后

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29260296/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 10:17:29  来源:igfitidea点击:

modify pseudo select :after in javascript

javascriptcsscss-selectors

提问by user596502

I have defined a css like

我已经定义了一个像

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

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

我想从 JS 动态更改高度属性。我可以使用

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

But I do not know how to change the height attribute. I tried to use setPropertybut it seems there is no such function available for pseudo-classes. Any ideas let me know.

但我不知道如何更改高度属性。我尝试使用,setProperty但似乎没有可用于伪类的功能。任何想法让我知道。

回答by radiaph

If that style comes from a CSS file, you'll have to search for it in document.styleSheets, which will be messy.

如果该样式来自 CSS 文件,则必须在 中搜索它document.styleSheets,这会很麻烦。

If you are open to dynamically creating a <style>element containing that CSS instead, you can modify it programmatically.

如果您愿意动态创建<style>包含该 CSS的元素,则可以通过编程方式对其进行修改。

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

回答by The Spooniest

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

像 :before 和 :after 这样的伪元素由 CSS 处理,而不是由 DOM 处理。因此,您需要采取不同的方法。

What you cando is find the CSS rule responsible for this pseudo-element, and change that.You do this using CSSOM, which is a rather different API, even though you first get access to it from the DOM.

可以做的是找到负责这个伪元素的 CSS 规则,然后改变它。您可以使用 CSSOM 来执行此操作,这是一个相当不同的 API,即使您首先从 DOM 访问它。

Unlike the DOM, CSS rules don't have ids or class names that can be searched for cleanly and quickly, so we have to search through the list of stylesheets and style rules. This can be expensive, so if it's possible to search for it only once, I strongly recommend doing that. Here's a quick-and-dirty way to do that:

与 DOM 不同,CSS 规则没有可以干净快速地搜索的 id 或类名,因此我们必须在样式表和样式规则列表中进行搜索。这可能很昂贵,因此如果只能搜索一次,我强烈建议这样做。这是一种快速而肮脏的方法:

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've got the rule you need, the rest is very similar to working with getComputedStyle(), or with a DOM element's styleattribute. The snippet above does it in a DOMContentLoaded event handler, but you should be able to do it at any point once things have loaded.

一旦你有了你需要的规则,剩下的就与使用 getComputedStyle() 或使用 DOM 元素的style属性非常相似。上面的代码片段在 DOMContentLoaded 事件处理程序中执行此操作,但是一旦加载完毕,您应该可以随时执行此操作。

There are a few caveats to be considered with this approach:

使用这种方法需要考虑一些注意事项:

  • When you change a CSS rule, that change gets reflected in every element that the rule selects.If you have a rule that affects many elements, and you need to change the way all those elements look, this is great. If you have a rule that affects many elements, but you only need to change the look of one of those elements, this isn't so good.
  • CSSOM's view of your selector text may not match what you wrote. This comes up in this very example, in fact, because your selector should read .slidingTag li::after(note the extra colon). The browser corrects this when it parses your CSS, and this is what CSSOM knows to look for.
  • Just because a rule says something doesn't mean the element will display that way. Anything that can override a CSS rule -element-specific styles, more specific rules elsewhere in the set, !importantdeclarations, and so on- can also override your changes.
  • This isn't a substitute for getComputedStyle(). That follows from the above: if something changes an element's presentation, that doesn't affect the underlying CSS rules. If anything, it is the opposite of getComputedStyle(): instead of gettingwhat an element currentlydisplays, it setswhat certain elements shoulddisplay (barring unforeseen circumstances).
  • 当您更改 CSS 规则时,该更改会反映在该规则选择的每个元素中。如果您有一个影响许多元素的规则,并且您需要更改所有这些元素的外观,这很好。如果您有一个影响许多元素的规则,但您只需要更改其中一个元素的外观,这不是很好。
  • CSSOM 对您的选择器文本的看法可能与您所写的不符。事实上,这个例子出现在这个例子中,因为你的选择器应该读取.slidingTag li::after(注意额外的冒号)。浏览器在解析您的 CSS 时会对此进行更正,这就是 CSSOM 知道要查找的内容。
  • 仅仅因为规则说了些什么并不意味着元素会以这种方式显示。任何可以覆盖 CSS 规则的东西——元素特定的样式、集合中其他地方的更具体的规则、!important声明等等——也可以覆盖你的更改。
  • 这不是getComputedStyle(). 从上面可以看出:如果某事改变了元素的表现形式,那不会影响底层的 CSS 规则。如果有的话,它是相反的getComputedStyle():它不是获取元素当前显示的内容,而是设置某些元素应该显示的内容(除非出现不可预见的情况)。

回答by Rui Nunes

You can add an extra class to you element that have a different property on the :after, like:

您可以向元素添加一个额外的类,该类在 上具有不同的属性:after,例如:

first you have this:

首先你有这个:

HTML:

HTML:

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


CSS:


CSS:

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

then you got this:

然后你得到了这个:

New class that will override the property height:

将覆盖该属性的新类height

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

final HTML:

最终的 HTML:

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

To do that with javascript:

用 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

cheers!

干杯!