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>
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…