修改伪选择:在javascript之后

时间:2015-03-25 15:45:59

标签: javascript css css-selectors

我已经定义了一个类似

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

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

获得房产
window.getComputedStyle(document.querySelector('.slidingTag'), 'li:after').getPropertyValue('height')

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

3 个答案:

答案 0 :(得分:8)

如果该样式来自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

答案 1 :(得分: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);
.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()相反:而不是获取 当前显示的元素,设置某些元素< em>应该显示(除非无法预料的情况)。

答案 2 :(得分:2)

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

首先你有这个:

<强> HTML:

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


    的 CSS:

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

然后你得到了这个:

将覆盖属性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

喝彩!