Skip to content

Instantly share code, notes, and snippets.

@garlicnation
Last active July 10, 2018 15:22
Show Gist options
  • Save garlicnation/7ecc2b7ad317816ddf642b3193fc0c90 to your computer and use it in GitHub Desktop.
Save garlicnation/7ecc2b7ad317816ddf642b3193fc0c90 to your computer and use it in GitHub Desktop.
Select inside shadow roots
/**
* Find all elements inside `root` that match `selector`, even inside shadow roots.
*/
function qsAllDom(root, selector, results){
if (!results) {
results = []
}
var newResults = root.querySelectorAll(selector);
for (var result of newResults) {
results.push(result);
}
var roots = root.getElementsByTagName('*');
for (var i = 0; i < roots.length; i++) {
var shadow = roots[i].shadowRoot;
if (!shadow) {
continue;
}
for (var j = 0; j < shadow.children.length; j++) {
qsAllDom(shadow.children[j], selector, results);
}
}
return results;
}
/**
* Find all elements inside `root` that match `selector`, even inside shadow roots.
* Fastest method as of 12/20/16.
*/
function qsAllDomNoRecursion(root, selector, results){
if (!results) {
results = []
}
var queue = [root];
var elements = [];
for (var i = 0; i <= elements.length; i++) {
if (i === elements.length) {
if (queue.length === 0) {
break;
}
let next = queue.pop();
elements = next.getElementsByTagName('*');
i = -1;
continue;
}
var element = elements[i];
if (element.matches && element.matches(selector)) {
results.push(element);
}
var shadow = element.shadowRoot;
if (shadow) {
for (var j = 0; j < shadow.children.length; j++) {
queue.push(shadow.children[j]);
}
}
}
return results;
}
/**
* Find all elements inside `root` that match `selector`, even inside shadow roots.
*/
function qsAllDomTreeWalker(root, selector, results){
if (!results) {
results = []
}
var queue = [];
const newWalker = (root) => document.createTreeWalker(
root,
NodeFilter.SHOW_ELEMENT
);
var walker = newWalker(root);
var candidate = walker.nextNode();
while (candidate) {
if (candidate.matches && candidate.matches(selector)) {
results.push(walker.currentNode);
}
if (candidate.shadowRoot) {
queue.push(candidate.shadowRoot);
}
candidate = walker.nextNode();
while (!candidate && queue.length > 0) {
walker = newWalker(queue.pop());
candidate = walker.nextNode();
}
}
return results;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment