Javascript 如何判断元素是否在阴影DOM中?
我有一个项目,我正在本地使用阴影DOM(不是通过多边形填充)。我想检测给定的Javascript 如何判断元素是否在阴影DOM中?,javascript,html,css-selectors,shadow-dom,Javascript,Html,Css Selectors,Shadow Dom,我有一个项目,我正在本地使用阴影DOM(不是通过多边形填充)。我想检测给定的元素是否包含在阴影DOM或灯光DOM中 我已经查看了元素的所有属性,但是似乎没有任何属性根据元素所在的DOM类型而有所不同 如何确定元素是阴影DOM还是灯光DOM的一部分 下面是一个关于在本问题中被认为是“阴影DOM”和“光DOM”的示例。 (浅根)•文档 (轻)•HTML (轻)车身 (轻)|•DIV (阴影根)|•阴影根 (阴影)|•DIV (阴影)|•IFRAME (浅根)|文档 (轻)|•HTML (轻)车
元素
是否包含在阴影DOM或灯光DOM中
我已经查看了元素的所有属性,但是似乎没有任何属性根据元素所在的DOM类型而有所不同
如何确定元素是阴影DOM还是灯光DOM的一部分
下面是一个关于在本问题中被认为是“阴影DOM”和“光DOM”的示例。 (浅根)•文档 (轻)•HTML (轻)车身 (轻)|•DIV (阴影根)|•阴影根 (阴影)|•DIV (阴影)|•IFRAME (浅根)|文档 (轻)|•HTML (轻)车身 (灯光)| |•DIV (阴影根)| |阴影根 (阴影)| | DIV (无)|•[第二份文件的独立DIV] (无)•[第一份文件的独立DIV]
isInShadow()测试文档-无法在堆栈Exchange的沙箱中运行
函数isInShadow(元素){
//待办事项
}
功能测试(){
//(浅根)•文档
//(轻)•HTML
var html=document.documentElement;
assert(isInShadow(html)==false);
//(轻)车身
var body=document.body;
断言(isInShadow(body)==false);
//(轻)|•DIV
var div=document.createElement('div');
附体儿童(div);
断言(isInShadow(div)==false);
//(阴影根)|•阴影根
var divShadow=div.createShadowRoot();
var shadowDiv=document.createElement('div');
divShadow.appendChild(shadowDiv);
//(阴影)|•DIV
断言(isInShadow(shadowDiv)==true);
//(阴影)|•IFRAME
var iframe=document.querySelector('iframe');
shadowDiv.appendChild(iframe);
断言(isInShadow(iframe)==true);
//(浅根)|文档
var iframeDocument=iframe.contentWindow.document;
//(轻)|•HTML
var iframeHtml=iframeDocument.documentElement;
assert(isInShadow(iframeHtml)==false);
//(轻)车身
var iframeBody=iframeDocument.body;
//
assert(isInShadow(iframeHtml)==false);
//(灯光)| |•DIV
var iframeDiv=iframeDocument.createElement('div');
iframeBody.appendChild(iframeDiv);
断言(isInShadow(iframeDiv)==false);
//(阴影根)| |阴影根
var iframeDivShadow=iframeDiv.createShadowRoot();
//(阴影)| | DIV
var iframeDivShadowDiv=iframeDocument.createElement('div');
appendChild(iframeDivShadowDiv);
断言(isInShadow(iframeDivShadowDiv)==true);
//(无)|•[第二份文件的独立DIV]
var iframeUnattached=iframeDocument.createElement('div');
assert(布尔值(isInShadow(iframeUnattached))==false);
//(无)•[第一份文件的独立DIV]
var rootUnattached=document.createElement('div');
assert(布尔值(isInShadow(rootUnattached))==false);
}
onload=函数main(){
控制台组(“测试”);
试一试{
test();
console.log(“测试完成”);
}最后{
console.groupEnd();
}
}
⚠️ 警告:折旧风险
::shadow
伪元素。下面的方法只要求它保留在静态选择器配置文件中,但将来也可能被弃用并删除
我们可以使用来确定元素是否附加到阴影DOM
当且仅当元素位于阴影DOM中时,我们将能够通过使用选择器:host
来识别具有阴影DOM的元素,::shadow
来查看这些阴影DOM,*
并匹配任何子体来匹配它
function isInShadow(element) {
return element.matches(':host::shadow *');
}
函数isInShadow(元素){
return元素。匹配(':host::shadow*');
}
控制台组(“测试”);
var lightElement=document.querySelector('div');
断言(isInShadow(lightElement)==false);
var shadowChild=document.createElement('div');
lightElement.createShadowRoot().appendChild(shadowChild);
断言(isInShadow(shadowChild)==true);
var orphanedElement=document.createElement('div');
assert(isInShadow(孤立元素)==false);
var orphanedShadowChild=document.createElement('div');
orphanedElement.createShadowRoot().appendChild(orphanedShadowChild);
断言(isInShadow(孤立阴影孩子)==true);
var fragmentChild=document.createElement('div');
document.createDocumentFragment().appendChild(fragmentChild);
断言(isInShadow(fragmentChild)==false);
console.log('Complete');
console.groupEnd()代码>
如果调用ShadowRoot的toString()
方法,它将返回“[object ShadowRoot]”
。根据这一事实,我的方法如下:
function isInShadow(node) {
var parent = (node && node.parentNode);
while(parent) {
if(parent.toString() === "[object ShadowRoot]") {
return true;
}
parent = parent.parentNode;
}
return false;
}
编辑
Jeremy Banks建议采用另一种循环方式。这种方法与我的有点不同:它还检查传递的节点本身,我没有这样做
function isInShadow(node) {
for (; node; node = node.parentNode) {
if (node.toString() === "[object ShadowRoot]") {
return true;
}
}
return false;
}
函数isInShadow(节点){
for(;node;node=node.parentNode){
if(node.toString()=“[对象阴影根]”){
返回true;
}
}
返回false;
}
控制台组(“测试”);
var lightElement=document.querySelector('div');
断言(isInShadow(lightElement)==false);
var shadowChild=document.createElement('div');
lightElement.createShadowRoot().appendChild(shadowChild);
断言(isInShadow(shadowChild)==true);
弗吉尼亚州
function isInShadow(node) {
for (; node; node = node.parentNode) {
if (node.toString() === "[object ShadowRoot]") {
return true;
}
}
return false;
}
function hasShadowParent(element) {
while(element.parentNode && (element = element.parentNode)){
if(element instanceof ShadowRoot){
return true;
}
}
return false;
}
<my-custom-element>
<shadowRoot>
<custom-element>
<div>I'm in Light DOM of "custom-element" and
in Shadow Root of "my-custom-element" at same time</div>
</custom-element>
</shadowRoot>
<div id="LDofMCE"> Im in Light DOM of "my-custom-element"</div>
<my-custom-element>
var isInLD = document.contains(NodeRef);
if(isInLD){
console.alert('Element is in the only available "global Light DOM"(document)');
} else {
console.log('Element is hidden in the shadow dom of some element');
}
function isInShadow(node) {
return node.getRootNode() instanceof ShadowRoot;
}