修改伪 select :after in javascript

modify pseudo select :after in javascript

我定义了一个css喜欢

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

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

得到 属性
window.getComputedStyle(document.querySelector('.slidingTag'), 'li:after').getPropertyValue('height')

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

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

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

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

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

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

访问它

与DOM不同,CSS规则没有ids或class名称可以干净快速地搜索,所以我们必须搜索样式表列表和样式规则。 这可能很昂贵,所以如果可以只搜索一次,我强烈建议这样做。这是一个快速而简单的方法:

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>

一旦您获得了所需的规则,剩下的就与使用 getComputedStyle() 或使用 DOM 元素的 style 属性非常相似.上面的代码片段是在 DOMContentLoaded 事件处理程序中执行的,但是您应该能够在加载内容后随时执行此操作。

使用此方法需要注意一些注意事项:

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

您可以向 :after 上具有不同 属性 的元素添加额外的 class,例如:

首先你有这个:

HTML:

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


CSS:

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

然后你得到了这个:

新 class 将覆盖 属性 height :

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

最终HTML:

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

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

干杯!