CSS阴影DOM:是否有/deep选择器的替代方案?

3
据我所知,/deep选择器已被弃用,无法选择影子DOM子元素。因此,我正在寻找另一种解决方案。
CSS作用域看起来提供了升级选择器的解决方案,但没有提供下降选择器的解决方案。
给定这个DOM:
<script>
    $('.child').addClass('reached');
</script>
<div id="parent">
    #shadow-root
        <div class="child"></div>
    /shadow-root
</div>

我该如何在脚本中编写选择器以到达 .child 元素?

谢谢您的帮助。


你是指类似于:slotted这样的东西吗?如果是的话,请查看https://dev59.com/m14c5IYBdhLWcg3wuMJ7#27629265。同时,从https://www.w3.org/TR/dom41/#shadow-tree-slots和https://www.w3.org/TR/css-scoping-1/#selectors-data-model开始阅读。 - TylerH
也许我错了,但是我没有成功使用::slotted来访问下层节点。 - hadf
jQuery从来没有设计用于使用shadow DOM。在处理Web组件和shadow DOM时,最好避免使用它。使用原生的API,如querySelectorquerySelectorAll。它们将为您节省大量的困惑和难度。 - Intervalia
好的,那你建议使用querySelector来解决问题吗? - hadf
一个单独的 querySelector 无法穿透 shadowDOM。相反,你需要使用一个 querySelector 获取组件,然后在元素的 shadowRoot 上使用第二个 querySelector - Intervalia
真正的问题是你为什么要这样做?一个组件应该与它的子组件进行交互,而不应该与其他任何东西进行交互。如果外部的某个元素正在操作组件的子组件,那么你就违反了一些关于清晰编码的规则。我唯一能想到需要这样做的情况是为了测试。 - Intervalia
1个回答

5

如何在脚本中编写选择器以访问.child元素?

要访问Shadow DOM中的元素,您应该在元素上使用shadowRoot属性。

var parent = document.querySelector( '#parent' )
var child = parent.shadowRoot.querySelector( '#child' )
child.classList.add( 'reached' )

注意:Shadow DOM 必须以开放模式创建。
var sh = parent.attachShadow( { mode: 'open' } )

var parent = document.querySelector( '#parent' )
var sh = parent.attachShadow( { mode: 'open' } )
sh.innerHTML = `<style>
                    div.reached { color: green }
                </style>
                <div id="child">Child</div>
                `
var child = parent.shadowRoot.querySelector( '#child' )
child.classList.add( 'reached' )
<div id="parent">
</div>

注意:只有在使用<slot>揭示轻DOM中的元素时才需要::slotted

是否有/deep选择器的替代方案?

简短的回答是没有。由于影子DOM旨在将其与主页面隔离,所以/deep有点像异端邪说。

一个非常新的提议,使用::part和::theme伪元素可以恢复一些控制,但它不会很快实现。

在此之前,主要的解决方法是使用CSS自定义属性

然而,这两种解决方案必须由Web组件设计者实现,否则无法被覆盖。


你好,谢谢你的回复。你的解决方案是一个JS解决方案。是否可能有一个CSS解决方案呢?我的意思是基于选择器的解决方案。 - hadf
1
不适用于全局CSS(除非你的被遮蔽元素设计用来处理特定的临时CSS变量)。对于Shadow DOM中的局部CSS,或许可以使用。这取决于你的需求(但根据你的问题描述,似乎你想要一个全局的/deep等效方式,答案是不行的。) - Supersharp
@hadf 欢迎你。我已经更新了我的答案。如果有具体的使用案例,请随时发布新问题。根据情况不同,有不同的解决方案(包括CSS变量和其他变通方法)。例如:https://dev59.com/Q1YN5IYBdhLWcg3wT2xa#47633167 - Supersharp

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