如何确定HTML元素是否具有伪元素?

时间:2016-10-23 18:45:23

标签: javascript html css css3 pseudo-element

有没有办法确定给定的HTML元素是否应用了伪元素(::before / ::after)而不调用

window.getComputedStyle(element, ":before/:after");

已编辑:答案为

getComputedStyle的问题在于性能。我需要验证页面上的每个元素是否有伪元素 - 这就是性能非常关键的原因。 我试图从document.styleSheets访问cssRules以找到选择器,最后使用:: before或:: after,删除它并找到与其余选择器匹配的元素,但是这个解决方案有它自己的问题:

  • 来自不同域的styleSheets无法访问
  • 可能需要检查数千个cssRule(再次表现)

我还尝试比较元素的大小和偏移量,有没有伪元素,但没有任何效果。即使没有准确的方法,我也很乐意找到一种方法来削减一定数量的元素,至少检查30%。

当我确定该元素有一个伪元素时,我终于可以调用getComputedStyle来研究伪元素样式并进行更改。这部分完美无缺。

已编辑:我无法控制源页面。页面样式可以从不同的域动态上传。假设我的代码是内容脚本或库,例如必须将所有伪元素前景更改为基于该伪元素的其他CSS属性计算的某种颜色。

所有主要问题是更改基于其他CSS属性,并且您无法在不实际检索伪元素的计算样式和计算更改的情况下为所有伪元素设置相同的样式。

例如,您有youtube.com页面,您需要找到所有伪元素和

  • 如果此伪元素具有背景图像,则缩放元素
  • 如果此伪元素只有文本,则将其颜色更改为红色
  • 等...

2 个答案:

答案 0 :(得分:2)

我认为getComputedStyle()是了解元素是否附加了伪元素的唯一可靠方法。

但由于无法从DOM方法编辑它,这意味着您必须在文档中附加新规则。

这是一个简单的解决方案,如上一次编辑中所述,您将对所有伪元素应用相同的规则,是使用通配符*选择器:

*:before,*:after{ /*your rules*/ }

var style = document.createElement('style');
style.innerHTML = `*:before,*:after{
  color: green !important;
}`;
setTimeout(function() {
  document.head.appendChild(style);
}, 1500);
div:before {
  content: 'hello';
  color: blue;
}
div:after {
  content: 'world';
  color: red;
}
<div></div>

答案 1 :(得分:1)

究竟是什么原因导致现有解决方案出现问题?

这种遍历元素的方法:

var allElements = document.getElementsByTagName("*");
for (var i = allElements.length; i--;) {
  //var usedStyle = window.getComputedStyle(allElements[i], ":before/:after");    
  ...
}

每1ms大约有数千元素。

getComputedStyle的调用不应该太慢,因为它会获取在调用时已经计算过的数据(在渲染文档上)。

所以这一切都应该足够快。是的,原则上是O(N)任务,但是运行一次,对吧?