修改伪选择:在javascript之后

use*_*502 8 javascript css css-selectors

我已经定义了一个类似的CSS

.slidingTag li:after {
  content: '';
  z-index: 3;
  height: 6px;
}
Run Code Online (Sandbox Code Playgroud)

我想从JS动态更改height属性.我可以使用该物业

window.getComputedStyle(document.querySelector('.slidingTag'), 'li:after').getPropertyValue('height')
Run Code Online (Sandbox Code Playgroud)

但我不知道如何更改height属性.我尝试使用,setProperty但似乎没有这样的函数可用于伪类.任何想法让我知道.

rad*_*aph 9

如果该样式来自CSS文件,您将不得不搜索它document.styleSheets,这将是凌乱的.

如果您愿意动态创建<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
Run Code Online (Sandbox Code Playgroud)


The*_*est 5

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

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

与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);
Run Code Online (Sandbox Code Playgroud)
.slidingTag {
  color: blue;
}
.slidingTag li {
  color: green;
}
.slidingTag li:after {
  content: "World";
  font-size: 32px;
}
Run Code Online (Sandbox Code Playgroud)
<ul class="slidingTag">
  <li class="selected">Hello</li>
  <li>World</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

一旦获得了所需的规则,其余部分与使用getComputedStyle()或DOM元素的style属性非常相似.上面的代码片段在DOMContentLoaded事件处理程序中执行,但是一旦加载了事物,您应该能够在任何时候执行它.

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

  • 更改CSS规则时,该更改将反映在规则选择的每个元素中.如果您有一个影响许多元素的规则,并且您需要更改所有这些元素的外观,这很好.如果您有一个影响许多元素的规则,但您只需要更改其中一个元素的外观,那就不太好了.
  • CSSOM的选择器文本视图可能与您编写的内容不匹配.事实上,这就出现在这个例子中,因为您的选择器应该读取.slidingTag li::after(注意额外的冒号).浏览器在解析CSS时会对此进行更正,这正是CSSOM所知道的.
  • 仅仅因为规则说某事并不意味着元素会以这种方式显示.任何可以覆盖CSS规则的元素 - 特定于元素的样式,集合中其他地方的更具体的规则,!important声明等等 - 也可以覆盖您的更改.
  • 这不是替代品getComputedStyle().从上面得出:如果某些内容改变了元素的表示,那么这不会影响底层的CSS规则.如果有的话,则与之相反getComputedStyle():它不是获取当前显示的元素,而是设置某些元素显示的内容(除非无法预料的情况).


小智 5

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

首先你有这个:

HTML:

<div class="slidingTag">
    <li>lorem ipsum</li>
</div>
Run Code Online (Sandbox Code Playgroud)


CSS:

.slidingTag li:after {
      content: '';
      z-index: 3;
      height: 6px;
    }
Run Code Online (Sandbox Code Playgroud)

然后你得到这个:

将覆盖该属性的新类height

.slidingTag-modifier li:after {
   content: '';
  z-index: 3;
  height: 10px !important;
}
Run Code Online (Sandbox Code Playgroud)

最终 HTML:

<div class="slidingTag slidingTag-modifier">
    <li>lorem ipsum</li>
</div>
Run Code Online (Sandbox Code Playgroud)

使用 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
Run Code Online (Sandbox Code Playgroud)

干杯!