我如何知道一个元素是否在一个阴影DOM? [英] How can I tell if an element is in a shadow DOM?

查看:141
本文介绍了我如何知道一个元素是否在一个阴影DOM?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个项目,我在本地使用阴影DOM(不通过polyfill)。我想检测一个给定的元素是否包含在一个shadow DOM或一个light DOM中。



I看过元素上的所有属性,但似乎没有任何因元素所在的DOM类型而异。



如何我可以确定元素是否是影子DOM或光DOM的一部分?







这里是为了这个问题的目的被认为是影子DOM和光DOM的示例。

 
(光根)•文档
(轻)•HTML
•BODY
(light)| •DIV
(shadow root)| •ShadowRoot
(shadow)| •DIV
(shadow)| •IFRAME
(光根)| •文档
(light)| •HTML
(light)| | •BODY
(light)| | •DIV
(shadow root)| | •ShadowRoot
(shadow)| | •DIV
(无)| •[第二个文档的未附加DIV]
(无)•[第一个文档的未附加DIV]

 <!doctype html>< title> isInShadow()测试文档 - 无法在Stack Exchange的沙盒中运行 

解决方案>

如果调用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;
}






/ strong>



Jeremy Banks提出了另一种循环方式。这个方法与我有点不同:它也检查传递的节点本身,我没有这样做。

  function isInShadow (node){
for(; node; node = node.parentNode){
if(node.toString()===[object ShadowRoot]){
return true;
}
}
return false;
}

  function isInShadow {for(; node; node = node.parentNode){if(node.toString()===[object ShadowRoot]){return true; }} return false;} console.group('Testing'); var lightElement = document.querySelector('div'); console.assert(isInShadow(lightElement)=== false); var shadowChild = document.createElement('div'); lightElement.createShadowRoot()appendChild(shadowChild); console.assert(isInShadow(shadowChild)=== true) ; var orphanedElement = document.createElement('div'); console.assert(isInShadow(orphanedElement)=== false); var orphanedShadowChild = document.createElement('div'); orphanedElement.createShadowRoot()appendChild(orphanedShadowChild); console.assert(isInShadow(orphanedShadowChild)=== true); var fragmentChild = document.createElement('div'); document.createDocumentFragment()appendChild(fragmentChild); console.assert(isInShadow(fragmentChild)=== false) ; console.log('Complete。'); console.groupEnd();  

 < div>< / div>  


I have a project where I'm using the shadow DOM natively (not through a polyfill). I'd like to detect if a given element is contained within a shadow DOM or a light DOM.

I've looked through all of the properties on the elements, but there don't seem to be any which vary based on the type of DOM an element is in.

How can I determine if an element is part of a shadow DOM or a light DOM?


Here is an example of what is considered "shadow DOM" and "light DOM" for the purpose of this question.

 (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>

解决方案

If you call a ShadowRoot's toString() method, it will return "[object ShadowRoot]". According to this fact, here's my approach:

function isInShadow(node) {
    var parent = (node && node.parentNode);
    while(parent) {
        if(parent.toString() === "[object ShadowRoot]") {
            return true;
        }
        parent = parent.parentNode;
    }
    return false;
}


EDIT

Jeremy Banks suggests an approach in another style of looping. This approach is a little different from mine: it also checks the passed node itself, which I didn't do.

function isInShadow(node) {
    for (; node; node = node.parentNode) {
        if (node.toString() === "[object ShadowRoot]") {
            return true;
        }
    }
    return false;
}

function isInShadow(node) {
    for (; node; node = node.parentNode) {
        if (node.toString() === "[object ShadowRoot]") {
            return true;
        }
    }
    return false;
}

console.group('Testing');

var lightElement = document.querySelector('div');    

console.assert(isInShadow(lightElement) === false);

var shadowChild = document.createElement('div');
lightElement.createShadowRoot().appendChild(shadowChild);

console.assert(isInShadow(shadowChild) === true);

var orphanedElement = document.createElement('div');

console.assert(isInShadow(orphanedElement) === false);

var orphanedShadowChild = document.createElement('div');
orphanedElement.createShadowRoot().appendChild(orphanedShadowChild);

console.assert(isInShadow(orphanedShadowChild) === true);

var fragmentChild = document.createElement('div');
document.createDocumentFragment().appendChild(fragmentChild);

console.assert(isInShadow(fragmentChild) === false);

console.log('Complete.');
console.groupEnd();

<div></div>

这篇关于我如何知道一个元素是否在一个阴影DOM?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆