如何获取伪元素?

81

我需要获取:after并将其分配给变量。这可能吗?

querySelectorAll不起作用。

alert(some_div_with_pseudo.querySelectorAll('::after')[0]) // undefined

1
你不能,正如“伪”这个名字所暗示的那样。它们不是实际 DOM 的一部分,对于 JavaScript 来说,它们是应用于实际元素的样式规则。 - somethinghere
1
JavaScript 绝对可以 读取/写入 CSS 伪 content;请参见下面的示例以了解写模式 - John
1
这个问题不是另一个问题的重复。您会注意到另一个问题涉及jQuery,而所选答案并未回答此问题。 - Manngo
6个回答

60

简短的回答是不行,还没有这个功能。

JavaScript可以访问DOM。在页面从HTML加载时构建DOM,在JavaScript修改它时进一步修改DOM。

伪元素是由CSS生成的,而不是HTML或JavaScript。它仅为了给CSS提供支撑而存在,但JavaScript完全不知道它的存在。

这就是正确的方式。在整体设计中,页面始于HTML。一方面,JavaScript可用于修改其行为和操作内容,而另一方面,CSS可用于控制结果的呈现:

HTML [→ JavaScript] → CSS → Result

你会发现CSS,包括伪元素,都在最后出现,因此JavaScript没有参与其中。

另请参见:

编辑

看来在现代 JavaScript 中,有一种使用 window.getComputedStyle(element,pseudoElement) 的解决方法:

var element = document.querySelector(' … ');
var styles = window.getComputedStyle(element,':after')
var content = styles['content'];

1
getComputedStyle的问题在于,如果您输入错误的文字,您将得到与未输入第二个变量相同的结果,例如getComputedStyle(element,':afterrrr')== getComputedStyle(element),因此该函数的行为很奇怪。 - Nathan B
有人知道如何在伪元素被:hover:active时获取更新的样式吗?似乎getComputedStyle只返回伪元素的原始样式。然而,当普通元素被:hover:active时,getComputedStyle会返回更新后的样式。 - Levi Uzodike
我不确定编辑是否是这个问题的正确解决方案,但它肯定是我遇到的问题的正确答案! - Staghouse
@NathanB 嗯,这个错误/bug和在querySelector中使用错误的选择器差不多,所以你对我的评论基本上是无关紧要的。所有这些都是字符串魔术值,直到发现错误才能发现它们... - undefined

41

3
它返回样式。我需要元素。 - A. Petrov
28
":after"是伪元素,不是真正的元素。你无法返回一个DOM节点,因为它并不是一个节点 - 你能做的只是获取样式 :) - MrBizle
@MrBizle 这是一个影子 DOM 元素。 - John Libes
1
@MrBizle,我该如何检查伪元素是否存在? - Kick Buttowski
1
有人知道如何在伪元素被:hover:active时获取更新后的样式吗?似乎getComputedStyle只返回伪元素的原始样式。但是,当普通元素被:hover:active时,getComputedStyle会返回更新后的样式。 - Levi Uzodike

5
我使用箭头指向内容和侧边栏将通过CSS伪元素切换打开或关闭的方向。以下代码是写模式,但也完全可以阅读CSS伪元素content
因为牵涉到一些内容,我也会发布先决条件(来源:JAB Creations网络平台JavaScript文档,如果有遗漏,请在那里查找),这样那些希望尝试的人可以相当快地做到。 CSS
#menu a[href*='sidebar']::after {content: '\2192' !important;}

JavaScript使用

css_rule_set('#menu a[href*="sidebar"]::after','content','"\u2192"','important');

JavaScript前提条件

var sidebar = 20;


function id_(id)
{
 return (document.getElementById(id)) ? document.getElementById(id) : false;
}


function css_rule_set(selector,property,value,important)
{
 try
 {
  for (var i = 0; i<document.styleSheets.length; i++)
  {
   var ss = document.styleSheets[i];
   var r = ss.cssRules ? ss.cssRules : ss.rules;

   for (var j = 0; j<r.length; j++)
   {
    if (r[j].selectorText && r[j].selectorText==selector)
    {
     if (typeof important=='undefined') {r[j].style.setProperty(property,value);}
     else {r[j].style.setProperty(property,value,'important');}
     break;
    }
   }
  }
 }
 catch(e) {if (e.name !== 'SecurityError') {console.log('Developer: '+e);}}
}


function sidebar_toggle()
{
 if (id_('menu_mobile')) {id_('menu_mobile').checked = false;}

 if (getComputedStyle(id_('side')).getPropertyValue('display') == 'none')
 {
  css_rule_set('#menu a[href*="sidebar"]::after','content','"\u2192"','important');

  if (is_mobile())
  {
   css_rule_set('main','display','none','important');
   css_rule_set('#side','width','100%','important');
   css_rule_set('#side','display','block','important');
  }
  else
  {
   css_rule_set('main','width',(100 - sidebar)+'%');
   css_rule_set('#side','display','block');
  }
 }
 else
 {
  css_rule_set('#menu a[href*="sidebar"]::after','content','"\u2190"','important');

  if (is_mobile())
  {
   css_rule_set('main','display','block','important');
   css_rule_set('main','width','100%','important');
   css_rule_set('#side','display','none','important');
  }
  else
  {
   css_rule_set('main','width','100%','important');
   css_rule_set('#side','display','none');
  }
 }

这是一个非常有趣的解决方案。如果我理解正确的话,您正在遍历styleSheet对象,查找其中与目标匹配的选择器(在伪元素'#menu a[href*="sidebar"]::after'的情况下),然后使用您提供的新值更新其中的单个声明?虽然这不是这个问题的用例,但是只有当已经存在针对伪元素的样式声明时,才能起作用,是吗? - Brice

3
改变或设置CSS伪元素的样式是一个棘手的问题,实际上你不能直接做到这一点,或者可能我还不知道方法,但我会和你分享一种技巧来完成这个任务。
- 使用CSS变量设计CSS伪元素,并使用JavaScript更改变量的值,这将更改CSS伪元素的样式。
CSS:
 #box::after{
 content: 'this is after';
 background-color: var(--boxAfterBackColor,red);
 position: absolute;
 top: -20px;
 right: 0px;
 font-size: var(--boxAfterFontSize,20px);
}

JavaScript:

let box = document.getElementById('box');
box.style.setProperty('--boxAfterBackColor','green');
box.style.setProperty('--boxAfterFontSize','50px');

这对我有用,希望它也能帮到你。祝你好运!


3
这太棒了!我遇到了一个不寻常的情况,这种方法是最好的选择。我想给一个React forwardRef组件添加样式。当我使用styled-components库和jest-styled-components时,jest快照中的forwardRef节点仍然具有随机的className。这种方法使我可以放弃styled-component,以便快照按预期工作。 - Stefan Musarra
迄今为止最好的答案。干得好! - undefined

2

在JavaScript中,有一种方法可以访问伪元素的值,而无需使用任何库。要获取该值,您需要使用“getComputedStyle”函数。第二个参数是可选的。

let elem = window.getComputedStyle(parent, ':before');
alert(elem.getPropertyValue('background'))

这将会弹出伪元素的值。

但是有没有一种方法可以列出所有的伪元素? - Nathan B

0

让 elem = window.getComputedStyle(document.querySelector('#item'), ':after'); console.log(elem.getPropertyValue('content'))


2
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接