据我所知,标准JavaScript无法获取::before
或::after
伪元素。 Element.children
不允许你这样做。
我知道必须有一种方法,至少在Chrome特权的Firefox附加代码中,因为它列出了页面中的每个::before
元素(显然getComputedStyle()
也适用于它,因为你可以在inspector中列出它的所有样式,用JavaScript编写。
这个API在哪里被记录下来,并且它只是在Firefox和Chrome浏览器中有所不同和特权 - 或者很快就会成为标准的东西?
答案 0 :(得分:4)
CSS生成的内容不是DOM的一部分,即使你得到它们,你也无法对::before
/ ::after
伪元素做很多事情。我能想到的唯一用例是:
访问伪元素上的CSS计算值。 window.getComputedStyle()通过可选的第二个参数支持此功能。
枚举生成的内容。你可以做到这一点:
或通过遍历DOM并检查(针对每个元素)其content
/ :before
的计算样式中是否有:after
。例如:
window.getComputedStyle(elt, ':before').content
获取CSS中定义的计数器的“实时”值,如How to access CSS generated content with JavaScript中所示 - 请参阅该问题以获取详细信息。
答案 1 :(得分:2)
至少在我看来,你的问题不明确完全你想要做什么或得到什么。
::before
和::after
:如果您想要实际插入内容,这是::before
和::after
CSS选择器所做的事情,那么最直接的等价物是Element.insertAdjacentHTML(position, text)
。在那种情况下:
相当于::before
:
Element.insertAdjacentHTML("beforebegin", "<p>Additional HTML content before element.</p>");
相当于::after
:
Element.insertAdjacentHTML("afterend", "<p>Additional HTML content after element.</p>");
Element.insertAdjacentHTML()
还有afterbegin
和beforeend
选项,可以在引用的Element的开头或结尾之前插入HTML文本。
您可以使用Node.insertBefore(newNode, referenceNode)
插入节点
对于::before
,它将是(在myNode之前插入newNode
):
myNode.parentNode.insertBefore(newNode, myNode);
对于::after
,它将是(在myNode之后插入newNode
):
myNode.parentNode.insertBefore(newNode, myNode.nextSibling);
如果您尝试获取DOM中较早的元素的引用,那么听起来您正在寻找Node.previousSibling
。如果您正在寻找对DOM中稍后元素的引用,那么您正在寻找Node.nextSibling
。
您也可能正在寻找Node中参考DOM walk order之前和之后的元素。但是,CSS选择器::before
和::after
确实不。但是,从你提到Page Inspector开始,听起来就像你想要的那样。如果是这样,那么您可以使用TreeWalker来遍历DOM树。
以下内容应该做你想要的(注意:目前未经测试,可能会遗漏一些东西。):
//referenceNode is the node for which we want to find the elements
// before and after in DOM walk order.
//Create the TreeWalker
let treeWalker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT,
{acceptNode: function(node) {
return NodeFilter.FILTER_ACCEPT;
}
},
false );
//Point the TreeWalker at the referenceNode.
treeWalker.currentNode = referenceNode;
//Get the node immediately prior to the referenceNode in DOM walk order
let thePreviousNode = treeWalker.previousNode();
//Point the TreeWalker back at the referenceNode.
treeWalker.currentNode = referenceNode;
//Get the node immediately after to the referenceNode in DOM walk order
let theNextNode = treeWalker.nextNode();
正如Nickolay所述,如果您需要页面检查器或DOM Inspector(documentation)提供的完整详细信息,那么您需要使用inIDeepTreeWalker 。但是,您不太可能需要或不需要使用Firefox特定非标准接口提供的详细信息。如果你想要了解如何构建XUL <toolbarbutton>
之类的东西(不是属性/属性,而是组成像<toolbarbutton>
这样的XUL元素的XBL,你只需要它)。对于您可能正在考虑的绝大多数内容,标准的TreeWalker应该没问题。
除了inIDeepTreeWalker
之外,以上所有内容都是JavaScript的标准部分,不需要提升权限(即不要求它在加载项中)。
答案 2 :(得分:0)
如果您想通过 Javascript 引用 (::before / ::after) 伪元素是因为您试图对其 CSS 进行更改,则可以通过向 main 添加一个新类来实现元素,然后在 CSS 中创建一个额外的样式,以便在您的新类应用于该元素时使用。
我将以 Stack Overflow 自己的汉堡按钮设计为例。
现场示例: https://jsfiddle.net/tb4f3zq6/5/
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Hamburger</title>
</head>
<body>
<div class='HamburgerContainer'>
<a class='HamburgerButton'></a>
</div>
</body>
</html>
CSS:
.HamburgerContainer {
display: flex;
height: 50px;
width: 44px;
flex-shrink: 0;
padding: 0;
align-items: center;
justify-content: center;
cursor: pointer;
}
.HamburgerButton {
width: 18px;
height: 2px;
background-color: gray;
position: relative !important;
}
.HamburgerButton::before {
position: absolute;
content: '';
left: 0;
top: 5px;
width: 18px;
height: 2px;
background-color: gray;
transition: all ease-in-out .1s;
}
.HamburgerButton::after {
position: absolute;
content: '';
left: 0;
top: -5px;
width: 18px;
height: 2px;
background-color: gray;
transition: all ease-in-out .1s;
}
/*new style after applying active class*/
.HamburgerButton.active {
background-color: transparent;
}
.HamburgerButton.active::after,
.HamburgerButton.active::before {
top: 0;
transform: rotate(45deg);
}
.HamburgerButton.active::before {
transform: rotate(-45deg);
}
JS:
const HamburgerContainer = document.getElementsByClassName('HamburgerContainer');
const HamburgerButton = document.getElementsByClassName('HamburgerButton');
let active = false;
HamburgerContainer[0].addEventListener('click', function(){ToggleHamburger();});
function ToggleHamburger(){
if(!active)
{
HamburgerButton[0].classList.add('active');
active = true;
}
else
{
HamburgerButton[0].classList.remove('active');
active = false;
}
}
答案 3 :(得分:-1)
您可以使用iniDOMUtils
- selectorMatchesElement()
功能。
您可以在此处阅读更多相关信息 - https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/inIDOMUtils#selectorMatchesElement%28%29