getElementsByTagName()
has 2 great features: it is fast and it is live. But what if I want to get p strong
. Of course I could refine a selection using getElementsByTagName()
again but wouldn't I lose the live effect for the new p
tags?
Is there a way to turn querySelectorAll
into a live selector?
Or... is there a way to use getElementsByTagName()
and getElementsByClassName()
to create a function that works in a similar way (at least with descendants) as querySelectorAll
but being live?
Consider using mutation observers. Watch for childList
with subtree: true
. When the notification arrives, you can examine each added node with matches
to see if it matches some selector.
function querySelectorAllLive(element, selector) {
// Initialize results with current nodes.
var result = Array.prototype.slice.call(element.querySelectorAll(selector));
// Create observer instance.
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
[].forEach.call(mutation.addedNodes, function(node) {
if (node.nodeType === Node.ELEMENT_NODE && node.matches(selector)) {
result.push(node);
}
});
});
});
// Set up observer.
observer.observe(element, { childList: true, subtree: true });
return result;
}
I don't think it is possible because subsequent changes of the DOM does not reflect in the NodeList object returned by the querySelectorAll() method.
Selectors-api W3C