我如何知道一个元素是否在一个阴影DOM? [英] How can I tell if an element is in a shadow 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屋!