Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何判断元素是否在阴影DOM中?_Javascript_Html_Css Selectors_Shadow Dom - Fatal编程技术网

Javascript 如何判断元素是否在阴影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”和“光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;
}