我在一个项目中使用了阴影DOM(不是通过多边形填充),我想检测一个给定的element
是否包含在阴影DOM或光照DOM中。
我已经查看了元素的所有属性,但似乎没有任何属性会根据元素所在的DOM类型而变化。
如何确定一个元素是阴影DOM还是光照DOM的一部分?
下面是一个示例,说明了针对此问题所考虑的“阴影DOM”和“轻型DOM”。
(light root) • Document
(light) • HTML
(light) | • BODY
(light) | • DIV
(shadow root) | • ShadowRoot
(shadow) | • DIV
(shadow) | • IFRAME
(light root) | • Document
(light) | • HTML
(light) | | • BODY
(light) | | • DIV
(shadow root) | | • ShadowRoot
(shadow) | | • DIV
(none) | • [Unattached DIV of second Document]
(none) • [Unattached DIV of first Document]
<!doctype html>
<title>
isInShadow() test document - can not run in Stack Exchange's sandbox
</title>
<iframe src="about:blank"></iframe>
<script>
function isInShadow(element) {
// TODO
}
function test() {
// (light root) • Document
// (light) • HTML
var html = document.documentElement;
console.assert(isInShadow(html) === false);
// (light) | • BODY
var body = document.body;
console.assert(isInShadow(body) === false);
// (light) | • DIV
var div = document.createElement('div');
body.appendChild(div);
console.assert(isInShadow(div) === false);
// (shadow root) | • ShadowRoot
var divShadow = div.createShadowRoot();
var shadowDiv = document.createElement('div');
divShadow.appendChild(shadowDiv);
// (shadow) | • DIV
console.assert(isInShadow(shadowDiv) === true);
// (shadow) | • IFRAME
var iframe = document.querySelector('iframe');
shadowDiv.appendChild(iframe);
console.assert(isInShadow(iframe) === true);
// (light root) | • Document
var iframeDocument = iframe.contentWindow.document;
// (light) | • HTML
var iframeHtml = iframeDocument.documentElement;
console.assert(isInShadow(iframeHtml) === false);
// (light) | | • BODY
var iframeBody = iframeDocument.body;
//
console.assert(isInShadow(iframeHtml) === false);
// (light) | | • DIV
var iframeDiv = iframeDocument.createElement('div');
iframeBody.appendChild(iframeDiv);
console.assert(isInShadow(iframeDiv) === false);
// (shadow root) | | • ShadowRoot
var iframeDivShadow = iframeDiv.createShadowRoot();
// (shadow) | | • DIV
var iframeDivShadowDiv = iframeDocument.createElement('div');
iframeDivShadow.appendChild(iframeDivShadowDiv);
console.assert(isInShadow(iframeDivShadowDiv) === true);
// (none) | • [Unattached DIV of second Document]
var iframeUnattached = iframeDocument.createElement('div');
console.assert(Boolean(isInShadow(iframeUnattached)) === false);
// (none) • [Unattached DIV of first Document]
var rootUnattached = document.createElement('div');
console.assert(Boolean(isInShadow(rootUnattached)) === false);
}
onload = function main() {
console.group('Testing');
try {
test();
console.log('Testing complete.');
} finally {
console.groupEnd();
}
}
</script>
7条答案
按热度按时间yacmzcpb1#
如果你调用一个ShadowRoot的
toString()
方法,它将返回"[object ShadowRoot]"
。根据这个事实,我的方法如下:Jeremy Banks提出了另一种循环方式,这种方式与我的方式略有不同:它还会检查传递的节点本身,我没有这么做。
一个二个一个一个
vhmi4jdf2#
您可以检查元素是否具有影子父元素,如下所示:
这里使用的是
instanceof
而不是.toString()
。ui7jx7zq3#
警告:弃用风险️ Warning: Deprecation Risk
::shadow
伪元素在动态选择器配置文件中已被弃用并将从中删除。下面的方法只要求它保留在静态选择器配置文件中,但将来也 * 可能 * 弃用并将其删除。Discussions are ongoing我们可以使用
Element
's.matches()
method来确定一个元素是否附加到了影子DOM。当且仅当元素在影子DOM中时,我们才能够通过使用选择器
:host
来识别具有影子DOM的元素,使用::shadow
来查找那些影子DOM,使用*
并匹配任何后代来匹配它。x一个一个一个一个x一个一个二个x
os8fio9y4#
shadowDOM中的元素可以使用
getRootNode
找到,如下所示。xhv8bpkk5#
让我们来了解灯光穹顶:
Light DOM是用户提供的托管影子根的元素的DOM。更多信息请阅读polymer-project。
https://www.polymer-project.org/platform/shadow-dom.html#shadow-dom-subtrees
这意味着:Light DOM总是****相对于下一个拥有影子根的祖先**。
元素可以是自定义元素的灯光dom的一部分,同时也可以是另一个自定义元素的阴影根的一部分**。
根据你的问题:
如果你想知道元素是否在影子根中,你只需要从文档中抓取元素。
你可以使用这种方法来处理其他元素,只要用"my-custom-element"替换"document",然后测试
div#LDofMCE
是否在相对于"my-custom-element"的Light DOM中。由于缺乏关于为什么你需要这些信息的信息,我无法接近...
"倒退"问题:* * 此元素是否在Light DOM中(如果您开始相对于文档进行搜索)?**:contains()不能提供答案,因为要在Light Dom中--其中一个元素祖先需要是影子宿主。
"直奔主题"
htrmnn0y6#
这可以检查节点或元素是否在shadow dom中,并且适用于iframe
或使用示例
qnakjoqk7#
您可以通过执行以下操作来检查shadowDOM中是否存在任何元素:
#document
,而一个阴影元素的根是#shadow-root
。true
,否则就是false
。